2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 2003
5 Copyright (C) Stefan Metzmacher 2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "lib/util/dlinklist.h"
24 #include "smb_server/smb_server.h"
25 #include "librpc/gen_ndr/ndr_misc.h"
26 #include "ntvfs/ntvfs.h"
27 #include "libcli/raw/libcliraw.h"
29 #define BLOB_CHECK(cmd) do { \
32 NT_STATUS_NOT_OK_RETURN(_status); \
35 #define BLOB_CHECK_MIN_SIZE(blob, size) do { \
36 if ((blob)->length < (size)) { \
37 return NT_STATUS_INFO_LENGTH_MISMATCH; \
41 /* grow the data size of a trans2 reply */
42 NTSTATUS
smbsrv_blob_grow_data(TALLOC_CTX
*mem_ctx
,
46 if (new_size
> blob
->length
) {
48 p
= talloc_realloc(mem_ctx
, blob
->data
, uint8_t, new_size
);
49 NT_STATUS_HAVE_NO_MEMORY(p
);
52 blob
->length
= new_size
;
56 /* grow the data, zero filling any new bytes */
57 NTSTATUS
smbsrv_blob_fill_data(TALLOC_CTX
*mem_ctx
,
61 uint32_t old_size
= blob
->length
;
62 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, new_size
));
63 if (new_size
> old_size
) {
64 memset(blob
->data
+ old_size
, 0, new_size
- old_size
);
70 pull a string from a blob in a trans2 request
72 size_t smbsrv_blob_pull_string(struct smbsrv_request
*req
,
73 const DATA_BLOB
*blob
,
79 /* we use STR_NO_RANGE_CHECK because the params are allocated
80 separately in a DATA_BLOB, so we need to do our own range
82 if (offset
>= blob
->length
) {
86 return req_pull_string(req
, str
,
88 blob
->length
- offset
,
89 STR_NO_RANGE_CHECK
| flags
);
93 push a string into the data section of a trans2 request
94 return the number of bytes consumed in the output
96 size_t smbsrv_blob_push_string(TALLOC_CTX
*mem_ctx
,
105 int alignment
= 0, ret
= 0, pkt_len
;
107 /* we use STR_NO_RANGE_CHECK because the params are allocated
108 separately in a DATA_BLOB, so we need to do our own range
110 if (!str
|| offset
>= blob
->length
) {
111 if (flags
& STR_LEN8BIT
) {
112 SCVAL(blob
->data
, len_offset
, 0);
114 SIVAL(blob
->data
, len_offset
, 0);
119 flags
|= STR_NO_RANGE_CHECK
;
121 if (dest_len
== -1 || (dest_len
> blob
->length
- offset
)) {
122 dest_len
= blob
->length
- offset
;
125 if (!(flags
& (STR_ASCII
|STR_UNICODE
))) {
126 flags
|= default_flags
;
129 if ((offset
&1) && (flags
& STR_UNICODE
) && !(flags
& STR_NOALIGN
)) {
132 SCVAL(blob
->data
+ offset
, 0, 0);
133 ret
= push_string(blob
->data
+ offset
+ 1, str
, dest_len
-1, flags
);
136 ret
= push_string(blob
->data
+ offset
, str
, dest_len
, flags
);
139 /* sometimes the string needs to be terminated, but the length
140 on the wire must not include the termination! */
143 if ((flags
& STR_LEN_NOTERM
) && (flags
& STR_TERMINATE
)) {
144 if ((flags
& STR_UNICODE
) && ret
>= 2) {
147 if ((flags
& STR_ASCII
) && ret
>= 1) {
152 if (flags
& STR_LEN8BIT
) {
153 SCVAL(blob
->data
, len_offset
, pkt_len
);
155 SIVAL(blob
->data
, len_offset
, pkt_len
);
158 return ret
+ alignment
;
162 append a string to the data section of a trans2 reply
163 len_offset points to the place in the packet where the length field
166 NTSTATUS
smbsrv_blob_append_string(TALLOC_CTX
*mem_ctx
,
175 const int max_bytes_per_char
= 3;
177 offset
= blob
->length
;
178 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, offset
+ (2+strlen_m(str
))*max_bytes_per_char
));
179 ret
= smbsrv_blob_push_string(mem_ctx
, blob
, len_offset
, offset
, str
, -1, default_flags
, flags
);
181 return NT_STATUS_FOOBAR
;
183 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, offset
+ ret
));
187 NTSTATUS
smbsrv_push_passthru_fsinfo(TALLOC_CTX
*mem_ctx
,
189 enum smb_fsinfo_level level
,
190 union smb_fsinfo
*fsinfo
,
191 int default_str_flags
)
197 case RAW_QFS_VOLUME_INFORMATION
:
198 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 18));
200 push_nttime(blob
->data
, 0, fsinfo
->volume_info
.out
.create_time
);
201 SIVAL(blob
->data
, 8, fsinfo
->volume_info
.out
.serial_number
);
202 SSVAL(blob
->data
, 16, 0); /* padding */
203 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
,
204 fsinfo
->volume_info
.out
.volume_name
.s
,
205 12, default_str_flags
,
210 case RAW_QFS_SIZE_INFORMATION
:
211 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 24));
213 SBVAL(blob
->data
, 0, fsinfo
->size_info
.out
.total_alloc_units
);
214 SBVAL(blob
->data
, 8, fsinfo
->size_info
.out
.avail_alloc_units
);
215 SIVAL(blob
->data
, 16, fsinfo
->size_info
.out
.sectors_per_unit
);
216 SIVAL(blob
->data
, 20, fsinfo
->size_info
.out
.bytes_per_sector
);
220 case RAW_QFS_DEVICE_INFORMATION
:
221 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 8));
223 SIVAL(blob
->data
, 0, fsinfo
->device_info
.out
.device_type
);
224 SIVAL(blob
->data
, 4, fsinfo
->device_info
.out
.characteristics
);
228 case RAW_QFS_ATTRIBUTE_INFORMATION
:
229 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 12));
231 SIVAL(blob
->data
, 0, fsinfo
->attribute_info
.out
.fs_attr
);
232 SIVAL(blob
->data
, 4, fsinfo
->attribute_info
.out
.max_file_component_length
);
233 /* this must not be null terminated or win98 gets
234 confused! also note that w2k3 returns this as
235 unicode even when ascii is negotiated */
236 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
,
237 fsinfo
->attribute_info
.out
.fs_type
.s
,
238 8, default_str_flags
,
243 case RAW_QFS_QUOTA_INFORMATION
:
244 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 48));
246 SBVAL(blob
->data
, 0, fsinfo
->quota_information
.out
.unknown
[0]);
247 SBVAL(blob
->data
, 8, fsinfo
->quota_information
.out
.unknown
[1]);
248 SBVAL(blob
->data
, 16, fsinfo
->quota_information
.out
.unknown
[2]);
249 SBVAL(blob
->data
, 24, fsinfo
->quota_information
.out
.quota_soft
);
250 SBVAL(blob
->data
, 32, fsinfo
->quota_information
.out
.quota_hard
);
251 SBVAL(blob
->data
, 40, fsinfo
->quota_information
.out
.quota_flags
);
256 case RAW_QFS_FULL_SIZE_INFORMATION
:
257 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 32));
259 SBVAL(blob
->data
, 0, fsinfo
->full_size_information
.out
.total_alloc_units
);
260 SBVAL(blob
->data
, 8, fsinfo
->full_size_information
.out
.call_avail_alloc_units
);
261 SBVAL(blob
->data
, 16, fsinfo
->full_size_information
.out
.actual_avail_alloc_units
);
262 SIVAL(blob
->data
, 24, fsinfo
->full_size_information
.out
.sectors_per_unit
);
263 SIVAL(blob
->data
, 28, fsinfo
->full_size_information
.out
.bytes_per_sector
);
267 case RAW_QFS_OBJECTID_INFORMATION
:
268 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 64));
270 BLOB_CHECK(ndr_push_struct_blob(&guid_blob
, mem_ctx
,
271 &fsinfo
->objectid_information
.out
.guid
,
272 (ndr_push_flags_fn_t
)ndr_push_GUID
));
273 memcpy(blob
->data
, guid_blob
.data
, guid_blob
.length
);
276 SBVAL(blob
->data
, 16 + 8*i
, fsinfo
->objectid_information
.out
.unknown
[i
]);
282 return NT_STATUS_INVALID_LEVEL
;
285 return NT_STATUS_INVALID_LEVEL
;
288 NTSTATUS
smbsrv_push_passthru_fileinfo(TALLOC_CTX
*mem_ctx
,
290 enum smb_fileinfo_level level
,
291 union smb_fileinfo
*st
,
292 int default_str_flags
)
298 case RAW_FILEINFO_BASIC_INFORMATION
:
299 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 40));
301 push_nttime(blob
->data
, 0, st
->basic_info
.out
.create_time
);
302 push_nttime(blob
->data
, 8, st
->basic_info
.out
.access_time
);
303 push_nttime(blob
->data
, 16, st
->basic_info
.out
.write_time
);
304 push_nttime(blob
->data
, 24, st
->basic_info
.out
.change_time
);
305 SIVAL(blob
->data
, 32, st
->basic_info
.out
.attrib
);
306 SIVAL(blob
->data
, 36, 0); /* padding */
309 case RAW_FILEINFO_NETWORK_OPEN_INFORMATION
:
310 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 56));
312 push_nttime(blob
->data
, 0, st
->network_open_information
.out
.create_time
);
313 push_nttime(blob
->data
, 8, st
->network_open_information
.out
.access_time
);
314 push_nttime(blob
->data
, 16, st
->network_open_information
.out
.write_time
);
315 push_nttime(blob
->data
, 24, st
->network_open_information
.out
.change_time
);
316 SBVAL(blob
->data
, 32, st
->network_open_information
.out
.alloc_size
);
317 SBVAL(blob
->data
, 40, st
->network_open_information
.out
.size
);
318 SIVAL(blob
->data
, 48, st
->network_open_information
.out
.attrib
);
319 SIVAL(blob
->data
, 52, 0); /* padding */
322 case RAW_FILEINFO_STANDARD_INFORMATION
:
323 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 24));
325 SBVAL(blob
->data
, 0, st
->standard_info
.out
.alloc_size
);
326 SBVAL(blob
->data
, 8, st
->standard_info
.out
.size
);
327 SIVAL(blob
->data
, 16, st
->standard_info
.out
.nlink
);
328 SCVAL(blob
->data
, 20, st
->standard_info
.out
.delete_pending
);
329 SCVAL(blob
->data
, 21, st
->standard_info
.out
.directory
);
330 SSVAL(blob
->data
, 22, 0); /* padding */
333 case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION
:
334 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 8));
336 SIVAL(blob
->data
, 0, st
->attribute_tag_information
.out
.attrib
);
337 SIVAL(blob
->data
, 4, st
->attribute_tag_information
.out
.reparse_tag
);
340 case RAW_FILEINFO_EA_INFORMATION
:
341 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 4));
343 SIVAL(blob
->data
, 0, st
->ea_info
.out
.ea_size
);
346 case RAW_FILEINFO_MODE_INFORMATION
:
347 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 4));
349 SIVAL(blob
->data
, 0, st
->mode_information
.out
.mode
);
352 case RAW_FILEINFO_ALIGNMENT_INFORMATION
:
353 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 4));
356 st
->alignment_information
.out
.alignment_requirement
);
359 case RAW_FILEINFO_ACCESS_INFORMATION
:
360 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 4));
362 SIVAL(blob
->data
, 0, st
->access_information
.out
.access_flags
);
365 case RAW_FILEINFO_POSITION_INFORMATION
:
366 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 8));
368 SBVAL(blob
->data
, 0, st
->position_information
.out
.position
);
371 case RAW_FILEINFO_COMPRESSION_INFORMATION
:
372 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 16));
374 SBVAL(blob
->data
, 0, st
->compression_info
.out
.compressed_size
);
375 SSVAL(blob
->data
, 8, st
->compression_info
.out
.format
);
376 SCVAL(blob
->data
, 10, st
->compression_info
.out
.unit_shift
);
377 SCVAL(blob
->data
, 11, st
->compression_info
.out
.chunk_shift
);
378 SCVAL(blob
->data
, 12, st
->compression_info
.out
.cluster_shift
);
379 SSVAL(blob
->data
, 13, 0); /* 3 bytes padding */
380 SCVAL(blob
->data
, 15, 0);
383 case RAW_FILEINFO_INTERNAL_INFORMATION
:
384 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 8));
386 SBVAL(blob
->data
, 0, st
->internal_information
.out
.file_id
);
389 case RAW_FILEINFO_ALL_INFORMATION
:
390 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 72));
392 push_nttime(blob
->data
, 0, st
->all_info
.out
.create_time
);
393 push_nttime(blob
->data
, 8, st
->all_info
.out
.access_time
);
394 push_nttime(blob
->data
, 16, st
->all_info
.out
.write_time
);
395 push_nttime(blob
->data
, 24, st
->all_info
.out
.change_time
);
396 SIVAL(blob
->data
, 32, st
->all_info
.out
.attrib
);
397 SIVAL(blob
->data
, 36, 0); /* padding */
398 SBVAL(blob
->data
, 40, st
->all_info
.out
.alloc_size
);
399 SBVAL(blob
->data
, 48, st
->all_info
.out
.size
);
400 SIVAL(blob
->data
, 56, st
->all_info
.out
.nlink
);
401 SCVAL(blob
->data
, 60, st
->all_info
.out
.delete_pending
);
402 SCVAL(blob
->data
, 61, st
->all_info
.out
.directory
);
403 SSVAL(blob
->data
, 62, 0); /* padding */
404 SIVAL(blob
->data
, 64, st
->all_info
.out
.ea_size
);
405 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
,
406 st
->all_info
.out
.fname
.s
,
407 68, default_str_flags
,
411 case RAW_FILEINFO_NAME_INFORMATION
:
412 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 4));
414 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
,
415 st
->name_info
.out
.fname
.s
,
416 0, default_str_flags
,
420 case RAW_FILEINFO_ALT_NAME_INFORMATION
:
421 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 4));
423 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
,
424 st
->alt_name_info
.out
.fname
.s
,
425 0, default_str_flags
,
429 case RAW_FILEINFO_STREAM_INFORMATION
:
430 for (i
=0;i
<st
->stream_info
.out
.num_streams
;i
++) {
431 uint32_t data_size
= blob
->length
;
434 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, data_size
+ 24));
435 data
= blob
->data
+ data_size
;
436 SBVAL(data
, 8, st
->stream_info
.out
.streams
[i
].size
);
437 SBVAL(data
, 16, st
->stream_info
.out
.streams
[i
].alloc_size
);
438 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
,
439 st
->stream_info
.out
.streams
[i
].stream_name
.s
,
440 data_size
+ 4, default_str_flags
,
442 if (i
== st
->stream_info
.out
.num_streams
- 1) {
443 SIVAL(blob
->data
, data_size
, 0);
445 BLOB_CHECK(smbsrv_blob_fill_data(mem_ctx
, blob
, (blob
->length
+7)&~7));
446 SIVAL(blob
->data
, data_size
,
447 blob
->length
- data_size
);
452 case RAW_FILEINFO_SMB2_ALL_EAS
:
453 /* if no eas are returned the backend should
454 * have returned NO_EAS_ON_FILE or NO_MORE_EAS
456 * so it's a programmer error if num_eas == 0
458 if (st
->all_eas
.out
.num_eas
== 0) {
459 smb_panic("0 eas for SMB2_ALL_EAS - programmer error in ntvfs backend");
462 list_size
= ea_list_size_chained(st
->all_eas
.out
.num_eas
,
463 st
->all_eas
.out
.eas
);
464 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, list_size
));
466 ea_put_list_chained(blob
->data
,
467 st
->all_eas
.out
.num_eas
,
468 st
->all_eas
.out
.eas
);
471 case RAW_FILEINFO_SMB2_ALL_INFORMATION
:
472 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, 0x64));
474 push_nttime(blob
->data
, 0x00, st
->all_info2
.out
.create_time
);
475 push_nttime(blob
->data
, 0x08, st
->all_info2
.out
.access_time
);
476 push_nttime(blob
->data
, 0x10, st
->all_info2
.out
.write_time
);
477 push_nttime(blob
->data
, 0x18, st
->all_info2
.out
.change_time
);
478 SIVAL(blob
->data
, 0x20, st
->all_info2
.out
.attrib
);
479 SIVAL(blob
->data
, 0x24, st
->all_info2
.out
.unknown1
);
480 SBVAL(blob
->data
, 0x28, st
->all_info2
.out
.alloc_size
);
481 SBVAL(blob
->data
, 0x30, st
->all_info2
.out
.size
);
482 SIVAL(blob
->data
, 0x38, st
->all_info2
.out
.nlink
);
483 SCVAL(blob
->data
, 0x3C, st
->all_info2
.out
.delete_pending
);
484 SCVAL(blob
->data
, 0x3D, st
->all_info2
.out
.directory
);
485 SSVAL(blob
->data
, 0x3E, 0); /* padding */
486 SBVAL(blob
->data
, 0x40, st
->all_info2
.out
.file_id
);
487 SIVAL(blob
->data
, 0x48, st
->all_info2
.out
.ea_size
);
488 SIVAL(blob
->data
, 0x4C, st
->all_info2
.out
.access_mask
);
489 SBVAL(blob
->data
, 0x50, st
->all_info2
.out
.position
);
490 SBVAL(blob
->data
, 0x58, st
->all_info2
.out
.mode
);
491 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
,
492 st
->all_info2
.out
.fname
.s
,
493 0x60, default_str_flags
,
498 return NT_STATUS_INVALID_LEVEL
;
501 return NT_STATUS_INVALID_LEVEL
;
504 NTSTATUS
smbsrv_pull_passthru_sfileinfo(TALLOC_CTX
*mem_ctx
,
505 enum smb_setfileinfo_level level
,
506 union smb_setfileinfo
*st
,
507 const DATA_BLOB
*blob
,
508 int default_str_flags
,
509 struct smbsrv_request
*req
)
515 case SMB_SFILEINFO_BASIC_INFORMATION
:
516 BLOB_CHECK_MIN_SIZE(blob
, 36);
518 st
->basic_info
.in
.create_time
= pull_nttime(blob
->data
, 0);
519 st
->basic_info
.in
.access_time
= pull_nttime(blob
->data
, 8);
520 st
->basic_info
.in
.write_time
= pull_nttime(blob
->data
, 16);
521 st
->basic_info
.in
.change_time
= pull_nttime(blob
->data
, 24);
522 st
->basic_info
.in
.attrib
= IVAL(blob
->data
, 32);
526 case SMB_SFILEINFO_DISPOSITION_INFORMATION
:
527 BLOB_CHECK_MIN_SIZE(blob
, 1);
529 st
->disposition_info
.in
.delete_on_close
= CVAL(blob
->data
, 0);
533 case SMB_SFILEINFO_ALLOCATION_INFORMATION
:
534 BLOB_CHECK_MIN_SIZE(blob
, 8);
536 st
->allocation_info
.in
.alloc_size
= BVAL(blob
->data
, 0);
540 case RAW_SFILEINFO_END_OF_FILE_INFORMATION
:
541 BLOB_CHECK_MIN_SIZE(blob
, 8);
543 st
->end_of_file_info
.in
.size
= BVAL(blob
->data
, 0);
547 case RAW_SFILEINFO_RENAME_INFORMATION
:
550 * TODO: get rid of smbsrv_request argument of
551 * smbsrv_blob_pull_string()
553 return NT_STATUS_NOT_IMPLEMENTED
;
555 BLOB_CHECK_MIN_SIZE(blob
, 12);
557 st
->rename_information
.in
.overwrite
= CVAL(blob
->data
, 0);
558 st
->rename_information
.in
.root_fid
= IVAL(blob
->data
, 4);
559 len
= IVAL(blob
->data
, 8);
560 str_blob
.data
= blob
->data
+12;
561 str_blob
.length
= MIN(blob
->length
, len
);
562 smbsrv_blob_pull_string(req
, &str_blob
, 0,
563 &st
->rename_information
.in
.new_name
,
565 if (st
->rename_information
.in
.new_name
== NULL
) {
566 return NT_STATUS_FOOBAR
;
571 case RAW_SFILEINFO_POSITION_INFORMATION
:
572 BLOB_CHECK_MIN_SIZE(blob
, 8);
574 st
->position_information
.in
.position
= BVAL(blob
->data
, 0);
578 case RAW_SFILEINFO_MODE_INFORMATION
:
579 BLOB_CHECK_MIN_SIZE(blob
, 4);
581 st
->mode_information
.in
.mode
= IVAL(blob
->data
, 0);
586 return NT_STATUS_INVALID_LEVEL
;
589 return NT_STATUS_INVALID_LEVEL
;
593 fill a single entry in a trans2 find reply
595 NTSTATUS
smbsrv_push_passthru_search(TALLOC_CTX
*mem_ctx
,
597 enum smb_search_data_level level
,
598 union smb_search_data
*file
,
599 int default_str_flags
)
602 uint_t ofs
= blob
->length
;
605 case RAW_SEARCH_DATA_DIRECTORY_INFO
:
606 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, ofs
+ 64));
607 data
= blob
->data
+ ofs
;
608 SIVAL(data
, 4, file
->directory_info
.file_index
);
609 push_nttime(data
, 8, file
->directory_info
.create_time
);
610 push_nttime(data
, 16, file
->directory_info
.access_time
);
611 push_nttime(data
, 24, file
->directory_info
.write_time
);
612 push_nttime(data
, 32, file
->directory_info
.change_time
);
613 SBVAL(data
, 40, file
->directory_info
.size
);
614 SBVAL(data
, 48, file
->directory_info
.alloc_size
);
615 SIVAL(data
, 56, file
->directory_info
.attrib
);
616 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
, file
->directory_info
.name
.s
,
617 ofs
+ 60, default_str_flags
,
618 STR_TERMINATE_ASCII
));
619 data
= blob
->data
+ ofs
;
620 SIVAL(data
, 0, blob
->length
- ofs
);
623 case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO
:
624 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, ofs
+ 68));
625 data
= blob
->data
+ ofs
;
626 SIVAL(data
, 4, file
->full_directory_info
.file_index
);
627 push_nttime(data
, 8, file
->full_directory_info
.create_time
);
628 push_nttime(data
, 16, file
->full_directory_info
.access_time
);
629 push_nttime(data
, 24, file
->full_directory_info
.write_time
);
630 push_nttime(data
, 32, file
->full_directory_info
.change_time
);
631 SBVAL(data
, 40, file
->full_directory_info
.size
);
632 SBVAL(data
, 48, file
->full_directory_info
.alloc_size
);
633 SIVAL(data
, 56, file
->full_directory_info
.attrib
);
634 SIVAL(data
, 64, file
->full_directory_info
.ea_size
);
635 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
, file
->full_directory_info
.name
.s
,
636 ofs
+ 60, default_str_flags
,
637 STR_TERMINATE_ASCII
));
638 data
= blob
->data
+ ofs
;
639 SIVAL(data
, 0, blob
->length
- ofs
);
642 case RAW_SEARCH_DATA_NAME_INFO
:
643 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, ofs
+ 12));
644 data
= blob
->data
+ ofs
;
645 SIVAL(data
, 4, file
->name_info
.file_index
);
646 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
, file
->name_info
.name
.s
,
647 ofs
+ 8, default_str_flags
,
648 STR_TERMINATE_ASCII
));
649 data
= blob
->data
+ ofs
;
650 SIVAL(data
, 0, blob
->length
- ofs
);
653 case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO
:
654 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, ofs
+ 94));
655 data
= blob
->data
+ ofs
;
656 SIVAL(data
, 4, file
->both_directory_info
.file_index
);
657 push_nttime(data
, 8, file
->both_directory_info
.create_time
);
658 push_nttime(data
, 16, file
->both_directory_info
.access_time
);
659 push_nttime(data
, 24, file
->both_directory_info
.write_time
);
660 push_nttime(data
, 32, file
->both_directory_info
.change_time
);
661 SBVAL(data
, 40, file
->both_directory_info
.size
);
662 SBVAL(data
, 48, file
->both_directory_info
.alloc_size
);
663 SIVAL(data
, 56, file
->both_directory_info
.attrib
);
664 SIVAL(data
, 64, file
->both_directory_info
.ea_size
);
665 SCVAL(data
, 69, 0); /* reserved */
666 memset(data
+70,0,24);
667 smbsrv_blob_push_string(mem_ctx
, blob
,
669 file
->both_directory_info
.short_name
.s
,
670 24, default_str_flags
,
671 STR_UNICODE
| STR_LEN8BIT
);
672 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
, file
->both_directory_info
.name
.s
,
673 ofs
+ 60, default_str_flags
,
674 STR_TERMINATE_ASCII
));
675 /* align the end of the blob on an even boundary */
676 if (blob
->length
& 1) {
677 BLOB_CHECK(smbsrv_blob_fill_data(blob
, blob
, blob
->length
+1));
679 data
= blob
->data
+ ofs
;
680 SIVAL(data
, 0, blob
->length
- ofs
);
683 case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO
:
684 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, ofs
+ 80));
685 data
= blob
->data
+ ofs
;
686 SIVAL(data
, 4, file
->id_full_directory_info
.file_index
);
687 push_nttime(data
, 8, file
->id_full_directory_info
.create_time
);
688 push_nttime(data
, 16, file
->id_full_directory_info
.access_time
);
689 push_nttime(data
, 24, file
->id_full_directory_info
.write_time
);
690 push_nttime(data
, 32, file
->id_full_directory_info
.change_time
);
691 SBVAL(data
, 40, file
->id_full_directory_info
.size
);
692 SBVAL(data
, 48, file
->id_full_directory_info
.alloc_size
);
693 SIVAL(data
, 56, file
->id_full_directory_info
.attrib
);
694 SIVAL(data
, 64, file
->id_full_directory_info
.ea_size
);
695 SIVAL(data
, 68, 0); /* padding */
696 SBVAL(data
, 72, file
->id_full_directory_info
.file_id
);
697 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
, file
->id_full_directory_info
.name
.s
,
698 ofs
+ 60, default_str_flags
,
699 STR_TERMINATE_ASCII
));
700 data
= blob
->data
+ ofs
;
701 SIVAL(data
, 0, blob
->length
- ofs
);
704 case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO
:
705 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx
, blob
, ofs
+ 104));
706 data
= blob
->data
+ ofs
;
707 SIVAL(data
, 4, file
->id_both_directory_info
.file_index
);
708 push_nttime(data
, 8, file
->id_both_directory_info
.create_time
);
709 push_nttime(data
, 16, file
->id_both_directory_info
.access_time
);
710 push_nttime(data
, 24, file
->id_both_directory_info
.write_time
);
711 push_nttime(data
, 32, file
->id_both_directory_info
.change_time
);
712 SBVAL(data
, 40, file
->id_both_directory_info
.size
);
713 SBVAL(data
, 48, file
->id_both_directory_info
.alloc_size
);
714 SIVAL(data
, 56, file
->id_both_directory_info
.attrib
);
715 SIVAL(data
, 64, file
->id_both_directory_info
.ea_size
);
716 SCVAL(data
, 69, 0); /* reserved */
717 memset(data
+70,0,26);
718 smbsrv_blob_push_string(mem_ctx
, blob
,
720 file
->id_both_directory_info
.short_name
.s
,
721 24, default_str_flags
,
722 STR_UNICODE
| STR_LEN8BIT
);
723 SBVAL(data
, 96, file
->id_both_directory_info
.file_id
);
724 BLOB_CHECK(smbsrv_blob_append_string(mem_ctx
, blob
, file
->id_both_directory_info
.name
.s
,
725 ofs
+ 60, default_str_flags
,
726 STR_TERMINATE_ASCII
));
727 data
= blob
->data
+ ofs
;
728 SIVAL(data
, 0, blob
->length
- ofs
);
732 return NT_STATUS_INVALID_LEVEL
;
735 return NT_STATUS_INVALID_LEVEL
;