s3-docs: manpage for "smbcontrol xx idmap"
[Samba.git] / source4 / libcli / raw / rawfileinfo.c
blob08598a2d64d070316f4dabcd7b8da4e535a3f575
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 io->streams =
55 talloc_realloc(mem_ctx, io->streams, struct stream_struct, n+1);
56 if (!io->streams) {
57 return NT_STATUS_NO_MEMORY;
59 nlen = IVAL(blob.data, ofs + 0x04);
60 io->streams[n].size = BVAL(blob.data, ofs + 0x08);
61 io->streams[n].alloc_size = BVAL(blob.data, ofs + 0x10);
62 if (nlen > blob.length - (ofs + 24)) {
63 return NT_STATUS_INFO_LENGTH_MISMATCH;
65 ret = convert_string_talloc(io->streams,
66 CH_UTF16, CH_UNIX,
67 blob.data+ofs+24, nlen, &vstr, NULL, false);
68 if (!ret) {
69 return NT_STATUS_ILLEGAL_CHARACTER;
71 io->streams[n].stream_name.s = (const char *)vstr;
72 io->streams[n].stream_name.private_length = nlen;
73 io->num_streams++;
74 len = IVAL(blob.data, ofs);
75 if (len > blob.length - ofs) {
76 return NT_STATUS_INFO_LENGTH_MISMATCH;
78 if (len == 0) break;
79 ofs += len;
82 return NT_STATUS_OK;
86 parse the fsinfo 'passthru' level replies
88 NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
89 enum smb_fileinfo_level level,
90 union smb_fileinfo *parms)
92 switch (level) {
93 case RAW_FILEINFO_BASIC_INFORMATION:
94 /* some servers return 40 bytes and some 36. w2k3 return 40, so thats
95 what we should do, but we need to accept 36 */
96 if (blob->length != 36) {
97 FINFO_CHECK_SIZE(40);
99 parms->basic_info.out.create_time = smbcli_pull_nttime(blob->data, 0);
100 parms->basic_info.out.access_time = smbcli_pull_nttime(blob->data, 8);
101 parms->basic_info.out.write_time = smbcli_pull_nttime(blob->data, 16);
102 parms->basic_info.out.change_time = smbcli_pull_nttime(blob->data, 24);
103 parms->basic_info.out.attrib = IVAL(blob->data, 32);
104 return NT_STATUS_OK;
106 case RAW_FILEINFO_STANDARD_INFORMATION:
107 FINFO_CHECK_SIZE(24);
108 parms->standard_info.out.alloc_size = BVAL(blob->data, 0);
109 parms->standard_info.out.size = BVAL(blob->data, 8);
110 parms->standard_info.out.nlink = IVAL(blob->data, 16);
111 parms->standard_info.out.delete_pending = CVAL(blob->data, 20);
112 parms->standard_info.out.directory = CVAL(blob->data, 21);
113 return NT_STATUS_OK;
115 case RAW_FILEINFO_EA_INFORMATION:
116 FINFO_CHECK_SIZE(4);
117 parms->ea_info.out.ea_size = IVAL(blob->data, 0);
118 return NT_STATUS_OK;
120 case RAW_FILEINFO_NAME_INFORMATION:
121 FINFO_CHECK_MIN_SIZE(4);
122 smbcli_blob_pull_string(NULL, mem_ctx, blob,
123 &parms->name_info.out.fname, 0, 4, STR_UNICODE);
124 return NT_STATUS_OK;
126 case RAW_FILEINFO_ALL_INFORMATION:
127 FINFO_CHECK_MIN_SIZE(72);
128 parms->all_info.out.create_time = smbcli_pull_nttime(blob->data, 0);
129 parms->all_info.out.access_time = smbcli_pull_nttime(blob->data, 8);
130 parms->all_info.out.write_time = smbcli_pull_nttime(blob->data, 16);
131 parms->all_info.out.change_time = smbcli_pull_nttime(blob->data, 24);
132 parms->all_info.out.attrib = IVAL(blob->data, 32);
133 parms->all_info.out.alloc_size = BVAL(blob->data, 40);
134 parms->all_info.out.size = BVAL(blob->data, 48);
135 parms->all_info.out.nlink = IVAL(blob->data, 56);
136 parms->all_info.out.delete_pending = CVAL(blob->data, 60);
137 parms->all_info.out.directory = CVAL(blob->data, 61);
138 #if 1
139 parms->all_info.out.ea_size = IVAL(blob->data, 64);
140 smbcli_blob_pull_string(NULL, mem_ctx, blob,
141 &parms->all_info.out.fname, 68, 72, STR_UNICODE);
142 #else
143 /* this is what the CIFS spec says - and its totally
144 wrong, but its useful having it here so we can
145 quickly adapt to broken servers when running
146 tests */
147 parms->all_info.out.ea_size = IVAL(blob->data, 72);
148 /* access flags 4 bytes at 76
149 current_position 8 bytes at 80
150 mode 4 bytes at 88
151 alignment 4 bytes at 92
153 smbcli_blob_pull_string(NULL, mem_ctx, blob,
154 &parms->all_info.out.fname, 96, 100, STR_UNICODE);
155 #endif
156 return NT_STATUS_OK;
158 case RAW_FILEINFO_ALT_NAME_INFORMATION:
159 FINFO_CHECK_MIN_SIZE(4);
160 smbcli_blob_pull_string(NULL, mem_ctx, blob,
161 &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE);
162 return NT_STATUS_OK;
164 case RAW_FILEINFO_STREAM_INFORMATION:
165 return smbcli_parse_stream_info(*blob, mem_ctx, &parms->stream_info.out);
167 case RAW_FILEINFO_INTERNAL_INFORMATION:
168 FINFO_CHECK_SIZE(8);
169 parms->internal_information.out.file_id = BVAL(blob->data, 0);
170 return NT_STATUS_OK;
172 case RAW_FILEINFO_ACCESS_INFORMATION:
173 FINFO_CHECK_SIZE(4);
174 parms->access_information.out.access_flags = IVAL(blob->data, 0);
175 return NT_STATUS_OK;
177 case RAW_FILEINFO_POSITION_INFORMATION:
178 FINFO_CHECK_SIZE(8);
179 parms->position_information.out.position = BVAL(blob->data, 0);
180 return NT_STATUS_OK;
182 case RAW_FILEINFO_MODE_INFORMATION:
183 FINFO_CHECK_SIZE(4);
184 parms->mode_information.out.mode = IVAL(blob->data, 0);
185 return NT_STATUS_OK;
187 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
188 FINFO_CHECK_SIZE(4);
189 parms->alignment_information.out.alignment_requirement
190 = IVAL(blob->data, 0);
191 return NT_STATUS_OK;
193 case RAW_FILEINFO_COMPRESSION_INFORMATION:
194 FINFO_CHECK_SIZE(16);
195 parms->compression_info.out.compressed_size = BVAL(blob->data, 0);
196 parms->compression_info.out.format = SVAL(blob->data, 8);
197 parms->compression_info.out.unit_shift = CVAL(blob->data, 10);
198 parms->compression_info.out.chunk_shift = CVAL(blob->data, 11);
199 parms->compression_info.out.cluster_shift = CVAL(blob->data, 12);
200 /* 3 bytes of padding */
201 return NT_STATUS_OK;
203 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
204 FINFO_CHECK_SIZE(56);
205 parms->network_open_information.out.create_time = smbcli_pull_nttime(blob->data, 0);
206 parms->network_open_information.out.access_time = smbcli_pull_nttime(blob->data, 8);
207 parms->network_open_information.out.write_time = smbcli_pull_nttime(blob->data, 16);
208 parms->network_open_information.out.change_time = smbcli_pull_nttime(blob->data, 24);
209 parms->network_open_information.out.alloc_size = BVAL(blob->data, 32);
210 parms->network_open_information.out.size = BVAL(blob->data, 40);
211 parms->network_open_information.out.attrib = IVAL(blob->data, 48);
212 return NT_STATUS_OK;
214 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
215 FINFO_CHECK_SIZE(8);
216 parms->attribute_tag_information.out.attrib = IVAL(blob->data, 0);
217 parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4);
218 return NT_STATUS_OK;
220 case RAW_FILEINFO_SMB2_ALL_EAS:
221 FINFO_CHECK_MIN_SIZE(4);
222 return ea_pull_list_chained(blob, mem_ctx,
223 &parms->all_eas.out.num_eas,
224 &parms->all_eas.out.eas);
226 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
227 FINFO_CHECK_MIN_SIZE(0x64);
228 parms->all_info2.out.create_time = smbcli_pull_nttime(blob->data, 0x00);
229 parms->all_info2.out.access_time = smbcli_pull_nttime(blob->data, 0x08);
230 parms->all_info2.out.write_time = smbcli_pull_nttime(blob->data, 0x10);
231 parms->all_info2.out.change_time = smbcli_pull_nttime(blob->data, 0x18);
232 parms->all_info2.out.attrib = IVAL(blob->data, 0x20);
233 parms->all_info2.out.unknown1 = IVAL(blob->data, 0x24);
234 parms->all_info2.out.alloc_size = BVAL(blob->data, 0x28);
235 parms->all_info2.out.size = BVAL(blob->data, 0x30);
236 parms->all_info2.out.nlink = IVAL(blob->data, 0x38);
237 parms->all_info2.out.delete_pending = CVAL(blob->data, 0x3C);
238 parms->all_info2.out.directory = CVAL(blob->data, 0x3D);
239 /* 0x3E-0x3F padding */
240 parms->all_info2.out.file_id = BVAL(blob->data, 0x40);
241 parms->all_info2.out.ea_size = IVAL(blob->data, 0x48);
242 parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C);
243 parms->all_info2.out.position = BVAL(blob->data, 0x50);
244 parms->all_info2.out.mode = IVAL(blob->data, 0x58);
245 parms->all_info2.out.alignment_requirement = IVAL(blob->data, 0x5C);
246 smbcli_blob_pull_string(NULL, mem_ctx, blob,
247 &parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE);
248 return NT_STATUS_OK;
250 case RAW_FILEINFO_SEC_DESC: {
251 enum ndr_err_code ndr_err;
253 parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor);
254 NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd);
256 ndr_err = ndr_pull_struct_blob(blob, mem_ctx,
257 parms->query_secdesc.out.sd,
258 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
259 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
260 return ndr_map_error2ntstatus(ndr_err);
263 return NT_STATUS_OK;
266 default:
267 break;
270 return NT_STATUS_INVALID_LEVEL;
274 /****************************************************************************
275 Handle qfileinfo/qpathinfo trans2 backend.
276 ****************************************************************************/
277 static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
278 TALLOC_CTX *mem_ctx,
279 union smb_fileinfo *parms,
280 DATA_BLOB *blob)
282 switch (parms->generic.level) {
283 case RAW_FILEINFO_GENERIC:
284 case RAW_FILEINFO_GETATTR:
285 case RAW_FILEINFO_GETATTRE:
286 case RAW_FILEINFO_SEC_DESC:
287 /* not handled here */
288 return NT_STATUS_INVALID_LEVEL;
290 case RAW_FILEINFO_STANDARD:
291 FINFO_CHECK_SIZE(22);
292 parms->standard.out.create_time = raw_pull_dos_date2(session->transport,
293 blob->data + 0);
294 parms->standard.out.access_time = raw_pull_dos_date2(session->transport,
295 blob->data + 4);
296 parms->standard.out.write_time = raw_pull_dos_date2(session->transport,
297 blob->data + 8);
298 parms->standard.out.size = IVAL(blob->data, 12);
299 parms->standard.out.alloc_size = IVAL(blob->data, 16);
300 parms->standard.out.attrib = SVAL(blob->data, 20);
301 return NT_STATUS_OK;
303 case RAW_FILEINFO_EA_SIZE:
304 FINFO_CHECK_SIZE(26);
305 parms->ea_size.out.create_time = raw_pull_dos_date2(session->transport,
306 blob->data + 0);
307 parms->ea_size.out.access_time = raw_pull_dos_date2(session->transport,
308 blob->data + 4);
309 parms->ea_size.out.write_time = raw_pull_dos_date2(session->transport,
310 blob->data + 8);
311 parms->ea_size.out.size = IVAL(blob->data, 12);
312 parms->ea_size.out.alloc_size = IVAL(blob->data, 16);
313 parms->ea_size.out.attrib = SVAL(blob->data, 20);
314 parms->ea_size.out.ea_size = IVAL(blob->data, 22);
315 return NT_STATUS_OK;
317 case RAW_FILEINFO_EA_LIST:
318 FINFO_CHECK_MIN_SIZE(4);
319 return ea_pull_list(blob, mem_ctx,
320 &parms->ea_list.out.num_eas,
321 &parms->ea_list.out.eas);
323 case RAW_FILEINFO_ALL_EAS:
324 FINFO_CHECK_MIN_SIZE(4);
325 return ea_pull_list(blob, mem_ctx,
326 &parms->all_eas.out.num_eas,
327 &parms->all_eas.out.eas);
329 case RAW_FILEINFO_IS_NAME_VALID:
330 /* no data! */
331 FINFO_CHECK_SIZE(0);
332 return NT_STATUS_OK;
334 case RAW_FILEINFO_BASIC_INFO:
335 case RAW_FILEINFO_BASIC_INFORMATION:
336 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
337 RAW_FILEINFO_BASIC_INFORMATION, parms);
339 case RAW_FILEINFO_STANDARD_INFO:
340 case RAW_FILEINFO_STANDARD_INFORMATION:
341 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
342 RAW_FILEINFO_STANDARD_INFORMATION, parms);
344 case RAW_FILEINFO_EA_INFO:
345 case RAW_FILEINFO_EA_INFORMATION:
346 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
347 RAW_FILEINFO_EA_INFORMATION, parms);
349 case RAW_FILEINFO_NAME_INFO:
350 case RAW_FILEINFO_NAME_INFORMATION:
351 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
352 RAW_FILEINFO_NAME_INFORMATION, parms);
354 case RAW_FILEINFO_ALL_INFO:
355 case RAW_FILEINFO_ALL_INFORMATION:
356 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
357 RAW_FILEINFO_ALL_INFORMATION, parms);
359 case RAW_FILEINFO_ALT_NAME_INFO:
360 case RAW_FILEINFO_ALT_NAME_INFORMATION:
361 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
362 RAW_FILEINFO_ALT_NAME_INFORMATION, parms);
364 case RAW_FILEINFO_STREAM_INFO:
365 case RAW_FILEINFO_STREAM_INFORMATION:
366 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
367 RAW_FILEINFO_STREAM_INFORMATION, parms);
369 case RAW_FILEINFO_INTERNAL_INFORMATION:
370 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
371 RAW_FILEINFO_INTERNAL_INFORMATION, parms);
373 case RAW_FILEINFO_ACCESS_INFORMATION:
374 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
375 RAW_FILEINFO_ACCESS_INFORMATION, parms);
377 case RAW_FILEINFO_POSITION_INFORMATION:
378 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
379 RAW_FILEINFO_POSITION_INFORMATION, parms);
381 case RAW_FILEINFO_MODE_INFORMATION:
382 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
383 RAW_FILEINFO_MODE_INFORMATION, parms);
385 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
386 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
387 RAW_FILEINFO_ALIGNMENT_INFORMATION, parms);
389 case RAW_FILEINFO_COMPRESSION_INFO:
390 case RAW_FILEINFO_COMPRESSION_INFORMATION:
391 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
392 RAW_FILEINFO_COMPRESSION_INFORMATION, parms);
394 case RAW_FILEINFO_UNIX_BASIC:
395 FINFO_CHECK_SIZE(100);
396 parms->unix_basic_info.out.end_of_file = BVAL(blob->data, 0);
397 parms->unix_basic_info.out.num_bytes = BVAL(blob->data, 8);
398 parms->unix_basic_info.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
399 parms->unix_basic_info.out.access_time = smbcli_pull_nttime(blob->data, 24);
400 parms->unix_basic_info.out.change_time = smbcli_pull_nttime(blob->data, 32);
401 parms->unix_basic_info.out.uid = BVAL(blob->data, 40);
402 parms->unix_basic_info.out.gid = BVAL(blob->data, 48);
403 parms->unix_basic_info.out.file_type = IVAL(blob->data, 52);
404 parms->unix_basic_info.out.dev_major = BVAL(blob->data, 60);
405 parms->unix_basic_info.out.dev_minor = BVAL(blob->data, 68);
406 parms->unix_basic_info.out.unique_id = BVAL(blob->data, 76);
407 parms->unix_basic_info.out.permissions = BVAL(blob->data, 84);
408 parms->unix_basic_info.out.nlink = BVAL(blob->data, 92);
409 return NT_STATUS_OK;
411 case RAW_FILEINFO_UNIX_INFO2:
412 FINFO_CHECK_SIZE(116);
413 parms->unix_info2.out.end_of_file = BVAL(blob->data, 0);
414 parms->unix_info2.out.num_bytes = BVAL(blob->data, 8);
415 parms->unix_info2.out.status_change_time = smbcli_pull_nttime(blob->data, 16);
416 parms->unix_info2.out.access_time = smbcli_pull_nttime(blob->data, 24);
417 parms->unix_info2.out.change_time = smbcli_pull_nttime(blob->data, 32);
418 parms->unix_info2.out.uid = BVAL(blob->data, 40);
419 parms->unix_info2.out.gid = BVAL(blob->data, 48);
420 parms->unix_info2.out.file_type = IVAL(blob->data, 52);
421 parms->unix_info2.out.dev_major = BVAL(blob->data, 60);
422 parms->unix_info2.out.dev_minor = BVAL(blob->data, 68);
423 parms->unix_info2.out.unique_id = BVAL(blob->data, 76);
424 parms->unix_info2.out.permissions = BVAL(blob->data, 84);
425 parms->unix_info2.out.nlink = BVAL(blob->data, 92);
426 parms->unix_info2.out.create_time = smbcli_pull_nttime(blob->data, 100);
427 parms->unix_info2.out.file_flags = IVAL(blob->data, 108);
428 parms->unix_info2.out.flags_mask = IVAL(blob->data, 112);
429 return NT_STATUS_OK;
431 case RAW_FILEINFO_UNIX_LINK:
432 smbcli_blob_pull_string(session, mem_ctx, blob,
433 &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE);
434 return NT_STATUS_OK;
436 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
437 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
438 RAW_FILEINFO_NETWORK_OPEN_INFORMATION, parms);
440 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
441 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
442 RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms);
444 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
445 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
446 RAW_FILEINFO_SMB2_ALL_INFORMATION, parms);
448 case RAW_FILEINFO_SMB2_ALL_EAS:
449 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
450 RAW_FILEINFO_SMB2_ALL_EAS, parms);
454 return NT_STATUS_INVALID_LEVEL;
458 /****************************************************************************
459 Very raw query file info - returns param/data blobs - (async send)
460 ****************************************************************************/
461 static struct smbcli_request *smb_raw_fileinfo_blob_send(struct smbcli_tree *tree,
462 uint16_t fnum,
463 uint16_t info_level,
464 DATA_BLOB data)
466 struct smb_trans2 tp;
467 uint16_t setup = TRANSACT2_QFILEINFO;
468 struct smbcli_request *req;
469 TALLOC_CTX *mem_ctx = talloc_init("raw_fileinfo");
471 tp.in.max_setup = 0;
472 tp.in.flags = 0;
473 tp.in.timeout = 0;
474 tp.in.setup_count = 1;
475 tp.in.data = data;
476 tp.in.max_param = 2;
477 tp.in.max_data = 0xFFFF;
478 tp.in.setup = &setup;
480 tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
481 if (!tp.in.params.data) {
482 talloc_free(mem_ctx);
483 return NULL;
486 SSVAL(tp.in.params.data, 0, fnum);
487 SSVAL(tp.in.params.data, 2, info_level);
489 req = smb_raw_trans2_send(tree, &tp);
491 talloc_free(mem_ctx);
493 return req;
497 /****************************************************************************
498 Very raw query file info - returns param/data blobs - (async recv)
499 ****************************************************************************/
500 static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req,
501 TALLOC_CTX *mem_ctx,
502 DATA_BLOB *blob)
504 struct smb_trans2 tp;
505 NTSTATUS status = smb_raw_trans2_recv(req, mem_ctx, &tp);
506 if (NT_STATUS_IS_OK(status)) {
507 *blob = tp.out.data;
509 return status;
512 /****************************************************************************
513 Very raw query path info - returns param/data blobs (async send)
514 ****************************************************************************/
515 static struct smbcli_request *smb_raw_pathinfo_blob_send(struct smbcli_tree *tree,
516 const char *fname,
517 uint16_t info_level,
518 DATA_BLOB data)
520 struct smb_trans2 tp;
521 uint16_t setup = TRANSACT2_QPATHINFO;
522 struct smbcli_request *req;
523 TALLOC_CTX *mem_ctx = talloc_init("raw_pathinfo");
525 tp.in.max_setup = 0;
526 tp.in.flags = 0;
527 tp.in.timeout = 0;
528 tp.in.setup_count = 1;
529 tp.in.data = data;
530 tp.in.max_param = 2;
531 tp.in.max_data = 0xFFFF;
532 tp.in.setup = &setup;
534 tp.in.params = data_blob_talloc(mem_ctx, NULL, 6);
535 if (!tp.in.params.data) {
536 talloc_free(mem_ctx);
537 return NULL;
540 SSVAL(tp.in.params.data, 0, info_level);
541 SIVAL(tp.in.params.data, 2, 0);
542 smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params,
543 fname, STR_TERMINATE);
545 req = smb_raw_trans2_send(tree, &tp);
547 talloc_free(mem_ctx);
549 return req;
552 /****************************************************************************
553 send a SMBgetatr (async send)
554 ****************************************************************************/
555 static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree,
556 union smb_fileinfo *parms)
558 struct smbcli_request *req;
560 req = smbcli_request_setup(tree, SMBgetatr, 0, 0);
561 if (!req) return NULL;
563 smbcli_req_append_ascii4(req, parms->getattr.in.file.path, STR_TERMINATE);
565 if (!smbcli_request_send(req)) {
566 smbcli_request_destroy(req);
567 return NULL;
570 return req;
573 /****************************************************************************
574 send a SMBgetatr (async recv)
575 ****************************************************************************/
576 static NTSTATUS smb_raw_getattr_recv(struct smbcli_request *req,
577 union smb_fileinfo *parms)
579 if (!smbcli_request_receive(req) ||
580 smbcli_request_is_error(req)) {
581 return smbcli_request_destroy(req);
584 SMBCLI_CHECK_WCT(req, 10);
585 parms->getattr.out.attrib = SVAL(req->in.vwv, VWV(0));
586 parms->getattr.out.write_time = raw_pull_dos_date3(req->transport,
587 req->in.vwv + VWV(1));
588 parms->getattr.out.size = IVAL(req->in.vwv, VWV(3));
590 failed:
591 return smbcli_request_destroy(req);
595 /****************************************************************************
596 Handle SMBgetattrE (async send)
597 ****************************************************************************/
598 static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree,
599 union smb_fileinfo *parms)
601 struct smbcli_request *req;
603 req = smbcli_request_setup(tree, SMBgetattrE, 1, 0);
604 if (!req) return NULL;
606 SSVAL(req->out.vwv, VWV(0), parms->getattre.in.file.fnum);
607 if (!smbcli_request_send(req)) {
608 smbcli_request_destroy(req);
609 return NULL;
612 return req;
615 /****************************************************************************
616 Handle SMBgetattrE (async send)
617 ****************************************************************************/
618 static NTSTATUS smb_raw_getattrE_recv(struct smbcli_request *req,
619 union smb_fileinfo *parms)
621 if (!smbcli_request_receive(req) ||
622 smbcli_request_is_error(req)) {
623 return smbcli_request_destroy(req);
626 SMBCLI_CHECK_WCT(req, 11);
627 parms->getattre.out.create_time = raw_pull_dos_date2(req->transport,
628 req->in.vwv + VWV(0));
629 parms->getattre.out.access_time = raw_pull_dos_date2(req->transport,
630 req->in.vwv + VWV(2));
631 parms->getattre.out.write_time = raw_pull_dos_date2(req->transport,
632 req->in.vwv + VWV(4));
633 parms->getattre.out.size = IVAL(req->in.vwv, VWV(6));
634 parms->getattre.out.alloc_size = IVAL(req->in.vwv, VWV(8));
635 parms->getattre.out.attrib = SVAL(req->in.vwv, VWV(10));
637 failed:
638 return smbcli_request_destroy(req);
642 /****************************************************************************
643 Query file info (async send)
644 ****************************************************************************/
645 struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
646 union smb_fileinfo *parms)
648 DATA_BLOB data;
649 struct smbcli_request *req;
651 /* pass off the non-trans2 level to specialised functions */
652 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
653 return smb_raw_getattrE_send(tree, parms);
655 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
656 return smb_raw_query_secdesc_send(tree, parms);
658 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
659 return NULL;
662 data = data_blob(NULL, 0);
664 if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
665 if (!ea_push_name_list(tree,
666 &data,
667 parms->ea_list.in.num_names,
668 parms->ea_list.in.ea_names)) {
669 return NULL;
673 req = smb_raw_fileinfo_blob_send(tree,
674 parms->generic.in.file.fnum,
675 parms->generic.level, data);
677 data_blob_free(&data);
679 return req;
682 /****************************************************************************
683 Query file info (async recv)
684 ****************************************************************************/
685 NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req,
686 TALLOC_CTX *mem_ctx,
687 union smb_fileinfo *parms)
689 DATA_BLOB blob;
690 NTSTATUS status;
691 struct smbcli_session *session = req?req->session:NULL;
693 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
694 return smb_raw_getattrE_recv(req, parms);
696 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
697 return smb_raw_query_secdesc_recv(req, mem_ctx, parms);
699 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
700 return smb_raw_getattr_recv(req, parms);
703 status = smb_raw_fileinfo_blob_recv(req, mem_ctx, &blob);
704 if (!NT_STATUS_IS_OK(status)) {
705 return status;
708 return smb_raw_info_backend(session, mem_ctx, parms, &blob);
711 /****************************************************************************
712 Query file info (sync interface)
713 ****************************************************************************/
714 _PUBLIC_ NTSTATUS smb_raw_fileinfo(struct smbcli_tree *tree,
715 TALLOC_CTX *mem_ctx,
716 union smb_fileinfo *parms)
718 struct smbcli_request *req = smb_raw_fileinfo_send(tree, parms);
719 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
722 /****************************************************************************
723 Query path info (async send)
724 ****************************************************************************/
725 _PUBLIC_ struct smbcli_request *smb_raw_pathinfo_send(struct smbcli_tree *tree,
726 union smb_fileinfo *parms)
728 DATA_BLOB data;
729 struct smbcli_request *req;
731 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
732 return smb_raw_getattr_send(tree, parms);
734 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
735 return NULL;
738 data = data_blob(NULL, 0);
740 if (parms->generic.level == RAW_FILEINFO_EA_LIST) {
741 if (!ea_push_name_list(tree,
742 &data,
743 parms->ea_list.in.num_names,
744 parms->ea_list.in.ea_names)) {
745 return NULL;
749 req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.file.path,
750 parms->generic.level, data);
751 data_blob_free(&data);
753 return req;
756 /****************************************************************************
757 Query path info (async recv)
758 ****************************************************************************/
759 _PUBLIC_ NTSTATUS smb_raw_pathinfo_recv(struct smbcli_request *req,
760 TALLOC_CTX *mem_ctx,
761 union smb_fileinfo *parms)
763 /* recv is idential to fileinfo */
764 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
767 /****************************************************************************
768 Query path info (sync interface)
769 ****************************************************************************/
770 _PUBLIC_ NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree,
771 TALLOC_CTX *mem_ctx,
772 union smb_fileinfo *parms)
774 struct smbcli_request *req = smb_raw_pathinfo_send(tree, parms);
775 return smb_raw_pathinfo_recv(req, mem_ctx, parms);