source: branches/samba-3.5.x/source4/libcli/raw/rawfileinfo.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 16 years ago

Samba 3.5.0: Initial import

File size: 27.0 KB
Line 
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
7
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.
12
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.
17
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/>.
20*/
21
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"
26
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; \
32}
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; \
37}
38
39/*
40 parse a stream information structure
41*/
42NTSTATUS smbcli_parse_stream_info(DATA_BLOB blob, TALLOC_CTX *mem_ctx,
43 struct stream_information *io)
44{
45 uint32_t ofs = 0;
46 io->num_streams = 0;
47 io->streams = NULL;
48
49 while (blob.length - ofs >= 24) {
50 uint_t 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;
58 }
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;
64 }
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;
70 }
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;
77 }
78 if (len == 0) break;
79 ofs += len;
80 }
81
82 return NT_STATUS_OK;
83}
84
85/*
86 parse the fsinfo 'passthru' level replies
87*/
88NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
89 enum smb_fileinfo_level level,
90 union smb_fileinfo *parms)
91{
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);
98 }
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;
105
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;
114
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;
119
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;
125
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
152 */
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;
157
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;
163
164 case RAW_FILEINFO_STREAM_INFORMATION:
165 return smbcli_parse_stream_info(*blob, mem_ctx, &parms->stream_info.out);
166
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;
171
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;
176
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;
181
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;
186
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;
192
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;
202
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;
213
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;
219
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);
225
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;
249
250 case RAW_FILEINFO_SEC_DESC: {
251 enum ndr_err_code ndr_err;
252
253 parms->query_secdesc.out.sd = talloc(mem_ctx, struct security_descriptor);
254 NT_STATUS_HAVE_NO_MEMORY(parms->query_secdesc.out.sd);
255
256 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL,
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);
261 }
262
263 return NT_STATUS_OK;
264 }
265
266 default:
267 break;
268 }
269
270 return NT_STATUS_INVALID_LEVEL;
271}
272
273
274/****************************************************************************
275 Handle qfileinfo/qpathinfo trans2 backend.
276****************************************************************************/
277static NTSTATUS smb_raw_info_backend(struct smbcli_session *session,
278 TALLOC_CTX *mem_ctx,
279 union smb_fileinfo *parms,
280 DATA_BLOB *blob)
281{
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;
289
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;
302
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;
316
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);
322
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);
328
329 case RAW_FILEINFO_IS_NAME_VALID:
330 /* no data! */
331 FINFO_CHECK_SIZE(0);
332 return NT_STATUS_OK;
333
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);
338
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);
343
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);
348
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);
353
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);
358
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);
363
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);
368
369 case RAW_FILEINFO_INTERNAL_INFORMATION:
370 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
371 RAW_FILEINFO_INTERNAL_INFORMATION, parms);
372
373 case RAW_FILEINFO_ACCESS_INFORMATION:
374 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
375 RAW_FILEINFO_ACCESS_INFORMATION, parms);
376
377 case RAW_FILEINFO_POSITION_INFORMATION:
378 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
379 RAW_FILEINFO_POSITION_INFORMATION, parms);
380
381 case RAW_FILEINFO_MODE_INFORMATION:
382 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
383 RAW_FILEINFO_MODE_INFORMATION, parms);
384
385 case RAW_FILEINFO_ALIGNMENT_INFORMATION:
386 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
387 RAW_FILEINFO_ALIGNMENT_INFORMATION, parms);
388
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);
393
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;
410
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;
430
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;
435
436 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION:
437 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
438 RAW_FILEINFO_NETWORK_OPEN_INFORMATION, parms);
439
440 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION:
441 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
442 RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms);
443
444 case RAW_FILEINFO_SMB2_ALL_INFORMATION:
445 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
446 RAW_FILEINFO_SMB2_ALL_INFORMATION, parms);
447
448 case RAW_FILEINFO_SMB2_ALL_EAS:
449 return smb_raw_fileinfo_passthru_parse(blob, mem_ctx,
450 RAW_FILEINFO_SMB2_ALL_EAS, parms);
451
452 }
453
454 return NT_STATUS_INVALID_LEVEL;
455}
456
457
458/****************************************************************************
459 Very raw query file info - returns param/data blobs - (async send)
460****************************************************************************/
461static 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)
465{
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");
470
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;
479
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;
484 }
485
486 SSVAL(tp.in.params.data, 0, fnum);
487 SSVAL(tp.in.params.data, 2, info_level);
488
489 req = smb_raw_trans2_send(tree, &tp);
490
491 talloc_free(mem_ctx);
492
493 return req;
494}
495
496
497/****************************************************************************
498 Very raw query file info - returns param/data blobs - (async recv)
499****************************************************************************/
500static NTSTATUS smb_raw_fileinfo_blob_recv(struct smbcli_request *req,
501 TALLOC_CTX *mem_ctx,
502 DATA_BLOB *blob)
503{
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;
508 }
509 return status;
510}
511
512/****************************************************************************
513 Very raw query path info - returns param/data blobs (async send)
514****************************************************************************/
515static 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)
519{
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");
524
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;
533
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;
538 }
539
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);
544
545 req = smb_raw_trans2_send(tree, &tp);
546
547 talloc_free(mem_ctx);
548
549 return req;
550}
551
552/****************************************************************************
553 send a SMBgetatr (async send)
554****************************************************************************/
555static struct smbcli_request *smb_raw_getattr_send(struct smbcli_tree *tree,
556 union smb_fileinfo *parms)
557{
558 struct smbcli_request *req;
559
560 req = smbcli_request_setup(tree, SMBgetatr, 0, 0);
561 if (!req) return NULL;
562
563 smbcli_req_append_ascii4(req, parms->getattr.in.file.path, STR_TERMINATE);
564
565 if (!smbcli_request_send(req)) {
566 smbcli_request_destroy(req);
567 return NULL;
568 }
569
570 return req;
571}
572
573/****************************************************************************
574 send a SMBgetatr (async recv)
575****************************************************************************/
576static NTSTATUS smb_raw_getattr_recv(struct smbcli_request *req,
577 union smb_fileinfo *parms)
578{
579 if (!smbcli_request_receive(req) ||
580 smbcli_request_is_error(req)) {
581 return smbcli_request_destroy(req);
582 }
583
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));
589
590failed:
591 return smbcli_request_destroy(req);
592}
593
594
595/****************************************************************************
596 Handle SMBgetattrE (async send)
597****************************************************************************/
598static struct smbcli_request *smb_raw_getattrE_send(struct smbcli_tree *tree,
599 union smb_fileinfo *parms)
600{
601 struct smbcli_request *req;
602
603 req = smbcli_request_setup(tree, SMBgetattrE, 1, 0);
604 if (!req) return NULL;
605
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;
610 }
611
612 return req;
613}
614
615/****************************************************************************
616 Handle SMBgetattrE (async send)
617****************************************************************************/
618static NTSTATUS smb_raw_getattrE_recv(struct smbcli_request *req,
619 union smb_fileinfo *parms)
620{
621 if (!smbcli_request_receive(req) ||
622 smbcli_request_is_error(req)) {
623 return smbcli_request_destroy(req);
624 }
625
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));
636
637failed:
638 return smbcli_request_destroy(req);
639}
640
641
642/****************************************************************************
643 Query file info (async send)
644****************************************************************************/
645struct smbcli_request *smb_raw_fileinfo_send(struct smbcli_tree *tree,
646 union smb_fileinfo *parms)
647{
648 DATA_BLOB data;
649 struct smbcli_request *req;
650
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);
654 }
655 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
656 return smb_raw_query_secdesc_send(tree, parms);
657 }
658 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
659 return NULL;
660 }
661
662 data = data_blob(NULL, 0);
663
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;
670 }
671 }
672
673 req = smb_raw_fileinfo_blob_send(tree,
674 parms->generic.in.file.fnum,
675 parms->generic.level, data);
676
677 data_blob_free(&data);
678
679 return req;
680}
681
682/****************************************************************************
683 Query file info (async recv)
684****************************************************************************/
685NTSTATUS smb_raw_fileinfo_recv(struct smbcli_request *req,
686 TALLOC_CTX *mem_ctx,
687 union smb_fileinfo *parms)
688{
689 DATA_BLOB blob;
690 NTSTATUS status;
691 struct smbcli_session *session = req?req->session:NULL;
692
693 if (parms->generic.level == RAW_FILEINFO_GETATTRE) {
694 return smb_raw_getattrE_recv(req, parms);
695 }
696 if (parms->generic.level == RAW_FILEINFO_SEC_DESC) {
697 return smb_raw_query_secdesc_recv(req, mem_ctx, parms);
698 }
699 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
700 return smb_raw_getattr_recv(req, parms);
701 }
702
703 status = smb_raw_fileinfo_blob_recv(req, mem_ctx, &blob);
704 if (!NT_STATUS_IS_OK(status)) {
705 return status;
706 }
707
708 return smb_raw_info_backend(session, mem_ctx, parms, &blob);
709}
710
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)
717{
718 struct smbcli_request *req = smb_raw_fileinfo_send(tree, parms);
719 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
720}
721
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)
727{
728 DATA_BLOB data;
729 struct smbcli_request *req;
730
731 if (parms->generic.level == RAW_FILEINFO_GETATTR) {
732 return smb_raw_getattr_send(tree, parms);
733 }
734 if (parms->generic.level >= RAW_FILEINFO_GENERIC) {
735 return NULL;
736 }
737
738 data = data_blob(NULL, 0);
739
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;
746 }
747 }
748
749 req = smb_raw_pathinfo_blob_send(tree, parms->generic.in.file.path,
750 parms->generic.level, data);
751 data_blob_free(&data);
752
753 return req;
754}
755
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)
762{
763 /* recv is idential to fileinfo */
764 return smb_raw_fileinfo_recv(req, mem_ctx, parms);
765}
766
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)
773{
774 struct smbcli_request *req = smb_raw_pathinfo_send(tree, parms);
775 return smb_raw_pathinfo_recv(req, mem_ctx, parms);
776}
Note: See TracBrowser for help on using the repository browser.