| 1 | /* | 
|---|
| 2 | Unix SMB/CIFS implementation. | 
|---|
| 3 |  | 
|---|
| 4 | Copyright (C) Andrew Tridgell 2003 | 
|---|
| 5 | Copyright (C) Stefan Metzmacher 2006 | 
|---|
| 6 |  | 
|---|
| 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 3 of the License, or | 
|---|
| 10 | (at your option) any later version. | 
|---|
| 11 |  | 
|---|
| 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. | 
|---|
| 16 |  | 
|---|
| 17 | You should have received a copy of the GNU General Public License | 
|---|
| 18 | along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
|---|
| 19 | */ | 
|---|
| 20 |  | 
|---|
| 21 | #include "includes.h" | 
|---|
| 22 | #include "smb_server/smb_server.h" | 
|---|
| 23 | #include "librpc/gen_ndr/ndr_misc.h" | 
|---|
| 24 | #include "libcli/raw/libcliraw.h" | 
|---|
| 25 | #include "libcli/raw/raw_proto.h" | 
|---|
| 26 |  | 
|---|
| 27 | #define BLOB_CHECK(cmd) do { \ | 
|---|
| 28 | NTSTATUS _status; \ | 
|---|
| 29 | _status = cmd; \ | 
|---|
| 30 | NT_STATUS_NOT_OK_RETURN(_status); \ | 
|---|
| 31 | } while (0) | 
|---|
| 32 |  | 
|---|
| 33 | #define BLOB_CHECK_MIN_SIZE(blob, size) do { \ | 
|---|
| 34 | if ((blob)->length < (size)) { \ | 
|---|
| 35 | return NT_STATUS_INVALID_PARAMETER; \ | 
|---|
| 36 | } \ | 
|---|
| 37 | } while (0) | 
|---|
| 38 |  | 
|---|
| 39 |  | 
|---|
| 40 | /* align the end of the blob on an 8 byte boundary */ | 
|---|
| 41 | #define BLOB_ALIGN(blob, alignment) do { \ | 
|---|
| 42 | if ((blob)->length & ((alignment)-1)) { \ | 
|---|
| 43 | uint8_t _pad = (alignment) - ((blob)->length & ((alignment)-1)); \ | 
|---|
| 44 | BLOB_CHECK(smbsrv_blob_fill_data(blob, blob, (blob)->length+_pad)); \ | 
|---|
| 45 | } \ | 
|---|
| 46 | } while (0) | 
|---|
| 47 |  | 
|---|
| 48 | /* grow the data size of a trans2 reply */ | 
|---|
| 49 | NTSTATUS smbsrv_blob_grow_data(TALLOC_CTX *mem_ctx, | 
|---|
| 50 | DATA_BLOB *blob, | 
|---|
| 51 | uint32_t new_size) | 
|---|
| 52 | { | 
|---|
| 53 | if (new_size > blob->length) { | 
|---|
| 54 | uint8_t *p; | 
|---|
| 55 | p = talloc_realloc(mem_ctx, blob->data, uint8_t, new_size); | 
|---|
| 56 | NT_STATUS_HAVE_NO_MEMORY(p); | 
|---|
| 57 | blob->data = p; | 
|---|
| 58 | } | 
|---|
| 59 | blob->length = new_size; | 
|---|
| 60 | return NT_STATUS_OK; | 
|---|
| 61 | } | 
|---|
| 62 |  | 
|---|
| 63 | /* grow the data, zero filling any new bytes */ | 
|---|
| 64 | NTSTATUS smbsrv_blob_fill_data(TALLOC_CTX *mem_ctx, | 
|---|
| 65 | DATA_BLOB *blob, | 
|---|
| 66 | uint32_t new_size) | 
|---|
| 67 | { | 
|---|
| 68 | uint32_t old_size = blob->length; | 
|---|
| 69 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, new_size)); | 
|---|
| 70 | if (new_size > old_size) { | 
|---|
| 71 | memset(blob->data + old_size, 0, new_size - old_size); | 
|---|
| 72 | } | 
|---|
| 73 | return NT_STATUS_OK; | 
|---|
| 74 | } | 
|---|
| 75 |  | 
|---|
| 76 | /* | 
|---|
| 77 | pull a string from a blob in a trans2 request | 
|---|
| 78 | */ | 
|---|
| 79 | size_t smbsrv_blob_pull_string(struct request_bufinfo *bufinfo, | 
|---|
| 80 | const DATA_BLOB *blob, | 
|---|
| 81 | uint16_t offset, | 
|---|
| 82 | const char **str, | 
|---|
| 83 | int flags) | 
|---|
| 84 | { | 
|---|
| 85 | *str = NULL; | 
|---|
| 86 | /* we use STR_NO_RANGE_CHECK because the params are allocated | 
|---|
| 87 | separately in a DATA_BLOB, so we need to do our own range | 
|---|
| 88 | checking */ | 
|---|
| 89 | if (offset >= blob->length) { | 
|---|
| 90 | return 0; | 
|---|
| 91 | } | 
|---|
| 92 |  | 
|---|
| 93 | return req_pull_string(bufinfo, str, | 
|---|
| 94 | blob->data + offset, | 
|---|
| 95 | blob->length - offset, | 
|---|
| 96 | STR_NO_RANGE_CHECK | flags); | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | /* | 
|---|
| 100 | push a string into the data section of a trans2 request | 
|---|
| 101 | return the number of bytes consumed in the output | 
|---|
| 102 | */ | 
|---|
| 103 | size_t smbsrv_blob_push_string(TALLOC_CTX *mem_ctx, | 
|---|
| 104 | DATA_BLOB *blob, | 
|---|
| 105 | uint32_t len_offset, | 
|---|
| 106 | uint32_t offset, | 
|---|
| 107 | const char *str, | 
|---|
| 108 | int dest_len, | 
|---|
| 109 | int default_flags, | 
|---|
| 110 | int flags) | 
|---|
| 111 | { | 
|---|
| 112 | int alignment = 0, ret = 0, pkt_len; | 
|---|
| 113 |  | 
|---|
| 114 | /* we use STR_NO_RANGE_CHECK because the params are allocated | 
|---|
| 115 | separately in a DATA_BLOB, so we need to do our own range | 
|---|
| 116 | checking */ | 
|---|
| 117 | if (!str || offset >= blob->length) { | 
|---|
| 118 | if (flags & STR_LEN8BIT) { | 
|---|
| 119 | SCVAL(blob->data, len_offset, 0); | 
|---|
| 120 | } else { | 
|---|
| 121 | SIVAL(blob->data, len_offset, 0); | 
|---|
| 122 | } | 
|---|
| 123 | return 0; | 
|---|
| 124 | } | 
|---|
| 125 |  | 
|---|
| 126 | flags |= STR_NO_RANGE_CHECK; | 
|---|
| 127 |  | 
|---|
| 128 | if (dest_len == -1 || (dest_len > blob->length - offset)) { | 
|---|
| 129 | dest_len = blob->length - offset; | 
|---|
| 130 | } | 
|---|
| 131 |  | 
|---|
| 132 | if (!(flags & (STR_ASCII|STR_UNICODE))) { | 
|---|
| 133 | flags |= default_flags; | 
|---|
| 134 | } | 
|---|
| 135 |  | 
|---|
| 136 | if ((offset&1) && (flags & STR_UNICODE) && !(flags & STR_NOALIGN)) { | 
|---|
| 137 | alignment = 1; | 
|---|
| 138 | if (dest_len > 0) { | 
|---|
| 139 | SCVAL(blob->data + offset, 0, 0); | 
|---|
| 140 | ret = push_string(blob->data + offset + 1, str, dest_len-1, flags); | 
|---|
| 141 | } | 
|---|
| 142 | } else { | 
|---|
| 143 | ret = push_string(blob->data + offset, str, dest_len, flags); | 
|---|
| 144 | } | 
|---|
| 145 |  | 
|---|
| 146 | /* sometimes the string needs to be terminated, but the length | 
|---|
| 147 | on the wire must not include the termination! */ | 
|---|
| 148 | pkt_len = ret; | 
|---|
| 149 |  | 
|---|
| 150 | if ((flags & STR_LEN_NOTERM) && (flags & STR_TERMINATE)) { | 
|---|
| 151 | if ((flags & STR_UNICODE) && ret >= 2) { | 
|---|
| 152 | pkt_len = ret-2; | 
|---|
| 153 | } | 
|---|
| 154 | if ((flags & STR_ASCII) && ret >= 1) { | 
|---|
| 155 | pkt_len = ret-1; | 
|---|
| 156 | } | 
|---|
| 157 | } | 
|---|
| 158 |  | 
|---|
| 159 | if (flags & STR_LEN8BIT) { | 
|---|
| 160 | SCVAL(blob->data, len_offset, pkt_len); | 
|---|
| 161 | } else { | 
|---|
| 162 | SIVAL(blob->data, len_offset, pkt_len); | 
|---|
| 163 | } | 
|---|
| 164 |  | 
|---|
| 165 | return ret + alignment; | 
|---|
| 166 | } | 
|---|
| 167 |  | 
|---|
| 168 | /* | 
|---|
| 169 | append a string to the data section of a trans2 reply | 
|---|
| 170 | len_offset points to the place in the packet where the length field | 
|---|
| 171 | should go | 
|---|
| 172 | */ | 
|---|
| 173 | NTSTATUS smbsrv_blob_append_string(TALLOC_CTX *mem_ctx, | 
|---|
| 174 | DATA_BLOB *blob, | 
|---|
| 175 | const char *str, | 
|---|
| 176 | uint_t len_offset, | 
|---|
| 177 | int default_flags, | 
|---|
| 178 | int flags) | 
|---|
| 179 | { | 
|---|
| 180 | size_t ret; | 
|---|
| 181 | uint32_t offset; | 
|---|
| 182 | const int max_bytes_per_char = 3; | 
|---|
| 183 |  | 
|---|
| 184 | offset = blob->length; | 
|---|
| 185 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, offset + (2+strlen_m(str))*max_bytes_per_char)); | 
|---|
| 186 | ret = smbsrv_blob_push_string(mem_ctx, blob, len_offset, offset, str, -1, default_flags, flags); | 
|---|
| 187 | if (ret < 0) { | 
|---|
| 188 | return NT_STATUS_FOOBAR; | 
|---|
| 189 | } | 
|---|
| 190 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, offset + ret)); | 
|---|
| 191 | return NT_STATUS_OK; | 
|---|
| 192 | } | 
|---|
| 193 |  | 
|---|
| 194 | NTSTATUS smbsrv_push_passthru_fsinfo(TALLOC_CTX *mem_ctx, | 
|---|
| 195 | DATA_BLOB *blob, | 
|---|
| 196 | enum smb_fsinfo_level level, | 
|---|
| 197 | union smb_fsinfo *fsinfo, | 
|---|
| 198 | int default_str_flags) | 
|---|
| 199 | { | 
|---|
| 200 | uint_t i; | 
|---|
| 201 | DATA_BLOB guid_blob; | 
|---|
| 202 |  | 
|---|
| 203 | switch (level) { | 
|---|
| 204 | case RAW_QFS_VOLUME_INFORMATION: | 
|---|
| 205 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 18)); | 
|---|
| 206 |  | 
|---|
| 207 | push_nttime(blob->data, 0, fsinfo->volume_info.out.create_time); | 
|---|
| 208 | SIVAL(blob->data,       8, fsinfo->volume_info.out.serial_number); | 
|---|
| 209 | SSVAL(blob->data,      16, 0); /* padding */ | 
|---|
| 210 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, | 
|---|
| 211 | fsinfo->volume_info.out.volume_name.s, | 
|---|
| 212 | 12, default_str_flags, | 
|---|
| 213 | STR_UNICODE)); | 
|---|
| 214 |  | 
|---|
| 215 | return NT_STATUS_OK; | 
|---|
| 216 |  | 
|---|
| 217 | case RAW_QFS_SIZE_INFORMATION: | 
|---|
| 218 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 24)); | 
|---|
| 219 |  | 
|---|
| 220 | SBVAL(blob->data,  0, fsinfo->size_info.out.total_alloc_units); | 
|---|
| 221 | SBVAL(blob->data,  8, fsinfo->size_info.out.avail_alloc_units); | 
|---|
| 222 | SIVAL(blob->data, 16, fsinfo->size_info.out.sectors_per_unit); | 
|---|
| 223 | SIVAL(blob->data, 20, fsinfo->size_info.out.bytes_per_sector); | 
|---|
| 224 |  | 
|---|
| 225 | return NT_STATUS_OK; | 
|---|
| 226 |  | 
|---|
| 227 | case RAW_QFS_DEVICE_INFORMATION: | 
|---|
| 228 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 8)); | 
|---|
| 229 |  | 
|---|
| 230 | SIVAL(blob->data,      0, fsinfo->device_info.out.device_type); | 
|---|
| 231 | SIVAL(blob->data,      4, fsinfo->device_info.out.characteristics); | 
|---|
| 232 |  | 
|---|
| 233 | return NT_STATUS_OK; | 
|---|
| 234 |  | 
|---|
| 235 | case RAW_QFS_ATTRIBUTE_INFORMATION: | 
|---|
| 236 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 12)); | 
|---|
| 237 |  | 
|---|
| 238 | SIVAL(blob->data, 0, fsinfo->attribute_info.out.fs_attr); | 
|---|
| 239 | SIVAL(blob->data, 4, fsinfo->attribute_info.out.max_file_component_length); | 
|---|
| 240 | /* this must not be null terminated or win98 gets | 
|---|
| 241 | confused!  also note that w2k3 returns this as | 
|---|
| 242 | unicode even when ascii is negotiated */ | 
|---|
| 243 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, | 
|---|
| 244 | fsinfo->attribute_info.out.fs_type.s, | 
|---|
| 245 | 8, default_str_flags, | 
|---|
| 246 | STR_UNICODE)); | 
|---|
| 247 | return NT_STATUS_OK; | 
|---|
| 248 |  | 
|---|
| 249 |  | 
|---|
| 250 | case RAW_QFS_QUOTA_INFORMATION: | 
|---|
| 251 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 48)); | 
|---|
| 252 |  | 
|---|
| 253 | SBVAL(blob->data,   0, fsinfo->quota_information.out.unknown[0]); | 
|---|
| 254 | SBVAL(blob->data,   8, fsinfo->quota_information.out.unknown[1]); | 
|---|
| 255 | SBVAL(blob->data,  16, fsinfo->quota_information.out.unknown[2]); | 
|---|
| 256 | SBVAL(blob->data,  24, fsinfo->quota_information.out.quota_soft); | 
|---|
| 257 | SBVAL(blob->data,  32, fsinfo->quota_information.out.quota_hard); | 
|---|
| 258 | SBVAL(blob->data,  40, fsinfo->quota_information.out.quota_flags); | 
|---|
| 259 |  | 
|---|
| 260 | return NT_STATUS_OK; | 
|---|
| 261 |  | 
|---|
| 262 |  | 
|---|
| 263 | case RAW_QFS_FULL_SIZE_INFORMATION: | 
|---|
| 264 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 32)); | 
|---|
| 265 |  | 
|---|
| 266 | SBVAL(blob->data,  0, fsinfo->full_size_information.out.total_alloc_units); | 
|---|
| 267 | SBVAL(blob->data,  8, fsinfo->full_size_information.out.call_avail_alloc_units); | 
|---|
| 268 | SBVAL(blob->data, 16, fsinfo->full_size_information.out.actual_avail_alloc_units); | 
|---|
| 269 | SIVAL(blob->data, 24, fsinfo->full_size_information.out.sectors_per_unit); | 
|---|
| 270 | SIVAL(blob->data, 28, fsinfo->full_size_information.out.bytes_per_sector); | 
|---|
| 271 |  | 
|---|
| 272 | return NT_STATUS_OK; | 
|---|
| 273 |  | 
|---|
| 274 | case RAW_QFS_OBJECTID_INFORMATION: { | 
|---|
| 275 | enum ndr_err_code ndr_err; | 
|---|
| 276 |  | 
|---|
| 277 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 64)); | 
|---|
| 278 |  | 
|---|
| 279 | ndr_err = ndr_push_struct_blob(&guid_blob, mem_ctx, NULL, | 
|---|
| 280 | &fsinfo->objectid_information.out.guid, | 
|---|
| 281 | (ndr_push_flags_fn_t)ndr_push_GUID); | 
|---|
| 282 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { | 
|---|
| 283 | BLOB_CHECK(ndr_map_error2ntstatus(ndr_err)); | 
|---|
| 284 | } | 
|---|
| 285 |  | 
|---|
| 286 | memcpy(blob->data, guid_blob.data, guid_blob.length); | 
|---|
| 287 |  | 
|---|
| 288 | for (i=0;i<6;i++) { | 
|---|
| 289 | SBVAL(blob->data, 16 + 8*i, fsinfo->objectid_information.out.unknown[i]); | 
|---|
| 290 | } | 
|---|
| 291 |  | 
|---|
| 292 | return NT_STATUS_OK; | 
|---|
| 293 | } | 
|---|
| 294 | default: | 
|---|
| 295 | return NT_STATUS_INVALID_LEVEL; | 
|---|
| 296 | } | 
|---|
| 297 |  | 
|---|
| 298 | return NT_STATUS_INVALID_LEVEL; | 
|---|
| 299 | } | 
|---|
| 300 |  | 
|---|
| 301 | NTSTATUS smbsrv_push_passthru_fileinfo(TALLOC_CTX *mem_ctx, | 
|---|
| 302 | DATA_BLOB *blob, | 
|---|
| 303 | enum smb_fileinfo_level level, | 
|---|
| 304 | union smb_fileinfo *st, | 
|---|
| 305 | int default_str_flags) | 
|---|
| 306 | { | 
|---|
| 307 | uint_t i; | 
|---|
| 308 | size_t list_size; | 
|---|
| 309 |  | 
|---|
| 310 | switch (level) { | 
|---|
| 311 | case RAW_FILEINFO_BASIC_INFORMATION: | 
|---|
| 312 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 40)); | 
|---|
| 313 |  | 
|---|
| 314 | push_nttime(blob->data,  0, st->basic_info.out.create_time); | 
|---|
| 315 | push_nttime(blob->data,  8, st->basic_info.out.access_time); | 
|---|
| 316 | push_nttime(blob->data, 16, st->basic_info.out.write_time); | 
|---|
| 317 | push_nttime(blob->data, 24, st->basic_info.out.change_time); | 
|---|
| 318 | SIVAL(blob->data,       32, st->basic_info.out.attrib); | 
|---|
| 319 | SIVAL(blob->data,       36, 0); /* padding */ | 
|---|
| 320 | return NT_STATUS_OK; | 
|---|
| 321 |  | 
|---|
| 322 | case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: | 
|---|
| 323 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 56)); | 
|---|
| 324 |  | 
|---|
| 325 | push_nttime(blob->data,  0, st->network_open_information.out.create_time); | 
|---|
| 326 | push_nttime(blob->data,  8, st->network_open_information.out.access_time); | 
|---|
| 327 | push_nttime(blob->data, 16, st->network_open_information.out.write_time); | 
|---|
| 328 | push_nttime(blob->data, 24, st->network_open_information.out.change_time); | 
|---|
| 329 | SBVAL(blob->data,       32, st->network_open_information.out.alloc_size); | 
|---|
| 330 | SBVAL(blob->data,       40, st->network_open_information.out.size); | 
|---|
| 331 | SIVAL(blob->data,       48, st->network_open_information.out.attrib); | 
|---|
| 332 | SIVAL(blob->data,       52, 0); /* padding */ | 
|---|
| 333 | return NT_STATUS_OK; | 
|---|
| 334 |  | 
|---|
| 335 | case RAW_FILEINFO_STANDARD_INFORMATION: | 
|---|
| 336 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 24)); | 
|---|
| 337 |  | 
|---|
| 338 | SBVAL(blob->data,  0, st->standard_info.out.alloc_size); | 
|---|
| 339 | SBVAL(blob->data,  8, st->standard_info.out.size); | 
|---|
| 340 | SIVAL(blob->data, 16, st->standard_info.out.nlink); | 
|---|
| 341 | SCVAL(blob->data, 20, st->standard_info.out.delete_pending); | 
|---|
| 342 | SCVAL(blob->data, 21, st->standard_info.out.directory); | 
|---|
| 343 | SSVAL(blob->data, 22, 0); /* padding */ | 
|---|
| 344 | return NT_STATUS_OK; | 
|---|
| 345 |  | 
|---|
| 346 | case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION: | 
|---|
| 347 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 8)); | 
|---|
| 348 |  | 
|---|
| 349 | SIVAL(blob->data,  0, st->attribute_tag_information.out.attrib); | 
|---|
| 350 | SIVAL(blob->data,  4, st->attribute_tag_information.out.reparse_tag); | 
|---|
| 351 | return NT_STATUS_OK; | 
|---|
| 352 |  | 
|---|
| 353 | case RAW_FILEINFO_EA_INFORMATION: | 
|---|
| 354 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4)); | 
|---|
| 355 |  | 
|---|
| 356 | SIVAL(blob->data,  0, st->ea_info.out.ea_size); | 
|---|
| 357 | return NT_STATUS_OK; | 
|---|
| 358 |  | 
|---|
| 359 | case RAW_FILEINFO_MODE_INFORMATION: | 
|---|
| 360 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4)); | 
|---|
| 361 |  | 
|---|
| 362 | SIVAL(blob->data,  0, st->mode_information.out.mode); | 
|---|
| 363 | return NT_STATUS_OK; | 
|---|
| 364 |  | 
|---|
| 365 | case RAW_FILEINFO_ALIGNMENT_INFORMATION: | 
|---|
| 366 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4)); | 
|---|
| 367 |  | 
|---|
| 368 | SIVAL(blob->data,  0, | 
|---|
| 369 | st->alignment_information.out.alignment_requirement); | 
|---|
| 370 | return NT_STATUS_OK; | 
|---|
| 371 |  | 
|---|
| 372 | case RAW_FILEINFO_ACCESS_INFORMATION: | 
|---|
| 373 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4)); | 
|---|
| 374 |  | 
|---|
| 375 | SIVAL(blob->data,  0, st->access_information.out.access_flags); | 
|---|
| 376 | return NT_STATUS_OK; | 
|---|
| 377 |  | 
|---|
| 378 | case RAW_FILEINFO_POSITION_INFORMATION: | 
|---|
| 379 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 8)); | 
|---|
| 380 |  | 
|---|
| 381 | SBVAL(blob->data,  0, st->position_information.out.position); | 
|---|
| 382 | return NT_STATUS_OK; | 
|---|
| 383 |  | 
|---|
| 384 | case RAW_FILEINFO_COMPRESSION_INFORMATION: | 
|---|
| 385 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 16)); | 
|---|
| 386 |  | 
|---|
| 387 | SBVAL(blob->data,  0, st->compression_info.out.compressed_size); | 
|---|
| 388 | SSVAL(blob->data,  8, st->compression_info.out.format); | 
|---|
| 389 | SCVAL(blob->data, 10, st->compression_info.out.unit_shift); | 
|---|
| 390 | SCVAL(blob->data, 11, st->compression_info.out.chunk_shift); | 
|---|
| 391 | SCVAL(blob->data, 12, st->compression_info.out.cluster_shift); | 
|---|
| 392 | SSVAL(blob->data, 13, 0); /* 3 bytes padding */ | 
|---|
| 393 | SCVAL(blob->data, 15, 0); | 
|---|
| 394 | return NT_STATUS_OK; | 
|---|
| 395 |  | 
|---|
| 396 | case RAW_FILEINFO_INTERNAL_INFORMATION: | 
|---|
| 397 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 8)); | 
|---|
| 398 |  | 
|---|
| 399 | SBVAL(blob->data,  0, st->internal_information.out.file_id); | 
|---|
| 400 | return NT_STATUS_OK; | 
|---|
| 401 |  | 
|---|
| 402 | case RAW_FILEINFO_ALL_INFORMATION: | 
|---|
| 403 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 72)); | 
|---|
| 404 |  | 
|---|
| 405 | push_nttime(blob->data,  0, st->all_info.out.create_time); | 
|---|
| 406 | push_nttime(blob->data,  8, st->all_info.out.access_time); | 
|---|
| 407 | push_nttime(blob->data, 16, st->all_info.out.write_time); | 
|---|
| 408 | push_nttime(blob->data, 24, st->all_info.out.change_time); | 
|---|
| 409 | SIVAL(blob->data,       32, st->all_info.out.attrib); | 
|---|
| 410 | SIVAL(blob->data,       36, 0); /* padding */ | 
|---|
| 411 | SBVAL(blob->data,       40, st->all_info.out.alloc_size); | 
|---|
| 412 | SBVAL(blob->data,       48, st->all_info.out.size); | 
|---|
| 413 | SIVAL(blob->data,       56, st->all_info.out.nlink); | 
|---|
| 414 | SCVAL(blob->data,       60, st->all_info.out.delete_pending); | 
|---|
| 415 | SCVAL(blob->data,       61, st->all_info.out.directory); | 
|---|
| 416 | SSVAL(blob->data,       62, 0); /* padding */ | 
|---|
| 417 | SIVAL(blob->data,       64, st->all_info.out.ea_size); | 
|---|
| 418 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, | 
|---|
| 419 | st->all_info.out.fname.s, | 
|---|
| 420 | 68, default_str_flags, | 
|---|
| 421 | STR_UNICODE)); | 
|---|
| 422 | return NT_STATUS_OK; | 
|---|
| 423 |  | 
|---|
| 424 | case RAW_FILEINFO_NAME_INFORMATION: | 
|---|
| 425 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4)); | 
|---|
| 426 |  | 
|---|
| 427 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, | 
|---|
| 428 | st->name_info.out.fname.s, | 
|---|
| 429 | 0, default_str_flags, | 
|---|
| 430 | STR_UNICODE)); | 
|---|
| 431 | return NT_STATUS_OK; | 
|---|
| 432 |  | 
|---|
| 433 | case RAW_FILEINFO_ALT_NAME_INFORMATION: | 
|---|
| 434 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 4)); | 
|---|
| 435 |  | 
|---|
| 436 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, | 
|---|
| 437 | st->alt_name_info.out.fname.s, | 
|---|
| 438 | 0, default_str_flags, | 
|---|
| 439 | STR_UNICODE)); | 
|---|
| 440 | return NT_STATUS_OK; | 
|---|
| 441 |  | 
|---|
| 442 | case RAW_FILEINFO_STREAM_INFORMATION: | 
|---|
| 443 | for (i=0;i<st->stream_info.out.num_streams;i++) { | 
|---|
| 444 | uint32_t data_size = blob->length; | 
|---|
| 445 | uint8_t *data; | 
|---|
| 446 |  | 
|---|
| 447 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, data_size + 24)); | 
|---|
| 448 | data = blob->data + data_size; | 
|---|
| 449 | SBVAL(data,  8, st->stream_info.out.streams[i].size); | 
|---|
| 450 | SBVAL(data, 16, st->stream_info.out.streams[i].alloc_size); | 
|---|
| 451 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, | 
|---|
| 452 | st->stream_info.out.streams[i].stream_name.s, | 
|---|
| 453 | data_size + 4, default_str_flags, | 
|---|
| 454 | STR_UNICODE)); | 
|---|
| 455 | if (i == st->stream_info.out.num_streams - 1) { | 
|---|
| 456 | SIVAL(blob->data, data_size, 0); | 
|---|
| 457 | } else { | 
|---|
| 458 | BLOB_CHECK(smbsrv_blob_fill_data(mem_ctx, blob, (blob->length+7)&~7)); | 
|---|
| 459 | SIVAL(blob->data, data_size, | 
|---|
| 460 | blob->length - data_size); | 
|---|
| 461 | } | 
|---|
| 462 | } | 
|---|
| 463 | return NT_STATUS_OK; | 
|---|
| 464 |  | 
|---|
| 465 | case RAW_FILEINFO_SMB2_ALL_EAS: | 
|---|
| 466 | /* if no eas are returned the backend should | 
|---|
| 467 | * have returned NO_EAS_ON_FILE or NO_MORE_EAS | 
|---|
| 468 | * | 
|---|
| 469 | * so it's a programmer error if num_eas == 0 | 
|---|
| 470 | */ | 
|---|
| 471 | if (st->all_eas.out.num_eas == 0) { | 
|---|
| 472 | smb_panic("0 eas for SMB2_ALL_EAS - programmer error in ntvfs backend"); | 
|---|
| 473 | } | 
|---|
| 474 |  | 
|---|
| 475 | list_size = ea_list_size_chained(st->all_eas.out.num_eas, | 
|---|
| 476 | st->all_eas.out.eas, 4); | 
|---|
| 477 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, list_size)); | 
|---|
| 478 |  | 
|---|
| 479 | ea_put_list_chained(blob->data, | 
|---|
| 480 | st->all_eas.out.num_eas, | 
|---|
| 481 | st->all_eas.out.eas, 4); | 
|---|
| 482 | return NT_STATUS_OK; | 
|---|
| 483 |  | 
|---|
| 484 | case RAW_FILEINFO_SMB2_ALL_INFORMATION: | 
|---|
| 485 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 0x64)); | 
|---|
| 486 |  | 
|---|
| 487 | push_nttime(blob->data, 0x00, st->all_info2.out.create_time); | 
|---|
| 488 | push_nttime(blob->data, 0x08, st->all_info2.out.access_time); | 
|---|
| 489 | push_nttime(blob->data, 0x10, st->all_info2.out.write_time); | 
|---|
| 490 | push_nttime(blob->data, 0x18, st->all_info2.out.change_time); | 
|---|
| 491 | SIVAL(blob->data,       0x20, st->all_info2.out.attrib); | 
|---|
| 492 | SIVAL(blob->data,       0x24, st->all_info2.out.unknown1); | 
|---|
| 493 | SBVAL(blob->data,       0x28, st->all_info2.out.alloc_size); | 
|---|
| 494 | SBVAL(blob->data,       0x30, st->all_info2.out.size); | 
|---|
| 495 | SIVAL(blob->data,       0x38, st->all_info2.out.nlink); | 
|---|
| 496 | SCVAL(blob->data,       0x3C, st->all_info2.out.delete_pending); | 
|---|
| 497 | SCVAL(blob->data,       0x3D, st->all_info2.out.directory); | 
|---|
| 498 | SSVAL(blob->data,       0x3E, 0); /* padding */ | 
|---|
| 499 | SBVAL(blob->data,       0x40, st->all_info2.out.file_id); | 
|---|
| 500 | SIVAL(blob->data,       0x48, st->all_info2.out.ea_size); | 
|---|
| 501 | SIVAL(blob->data,       0x4C, st->all_info2.out.access_mask); | 
|---|
| 502 | SBVAL(blob->data,       0x50, st->all_info2.out.position); | 
|---|
| 503 | SIVAL(blob->data,       0x58, st->all_info2.out.mode); | 
|---|
| 504 | SIVAL(blob->data,       0x5C, st->all_info2.out.alignment_requirement); | 
|---|
| 505 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, | 
|---|
| 506 | st->all_info2.out.fname.s, | 
|---|
| 507 | 0x60, default_str_flags, | 
|---|
| 508 | STR_UNICODE)); | 
|---|
| 509 | return NT_STATUS_OK; | 
|---|
| 510 |  | 
|---|
| 511 | default: | 
|---|
| 512 | return NT_STATUS_INVALID_LEVEL; | 
|---|
| 513 | } | 
|---|
| 514 |  | 
|---|
| 515 | return NT_STATUS_INVALID_LEVEL; | 
|---|
| 516 | } | 
|---|
| 517 |  | 
|---|
| 518 | NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, | 
|---|
| 519 | enum smb_setfileinfo_level level, | 
|---|
| 520 | union smb_setfileinfo *st, | 
|---|
| 521 | const DATA_BLOB *blob, | 
|---|
| 522 | int default_str_flags, | 
|---|
| 523 | struct request_bufinfo *bufinfo) | 
|---|
| 524 | { | 
|---|
| 525 | uint32_t len, ofs; | 
|---|
| 526 | DATA_BLOB str_blob; | 
|---|
| 527 |  | 
|---|
| 528 | switch (level) { | 
|---|
| 529 | case SMB_SFILEINFO_BASIC_INFORMATION: | 
|---|
| 530 | BLOB_CHECK_MIN_SIZE(blob, 40); | 
|---|
| 531 |  | 
|---|
| 532 | st->basic_info.in.create_time = pull_nttime(blob->data,  0); | 
|---|
| 533 | st->basic_info.in.access_time = pull_nttime(blob->data,  8); | 
|---|
| 534 | st->basic_info.in.write_time =  pull_nttime(blob->data, 16); | 
|---|
| 535 | st->basic_info.in.change_time = pull_nttime(blob->data, 24); | 
|---|
| 536 | st->basic_info.in.attrib      = IVAL(blob->data,        32); | 
|---|
| 537 | st->basic_info.in.reserved    = IVAL(blob->data,        36); | 
|---|
| 538 |  | 
|---|
| 539 | return NT_STATUS_OK; | 
|---|
| 540 |  | 
|---|
| 541 | case SMB_SFILEINFO_DISPOSITION_INFORMATION: | 
|---|
| 542 | BLOB_CHECK_MIN_SIZE(blob, 1); | 
|---|
| 543 |  | 
|---|
| 544 | st->disposition_info.in.delete_on_close = CVAL(blob->data, 0); | 
|---|
| 545 |  | 
|---|
| 546 | return NT_STATUS_OK; | 
|---|
| 547 |  | 
|---|
| 548 | case SMB_SFILEINFO_ALLOCATION_INFORMATION: | 
|---|
| 549 | BLOB_CHECK_MIN_SIZE(blob, 8); | 
|---|
| 550 |  | 
|---|
| 551 | st->allocation_info.in.alloc_size = BVAL(blob->data, 0); | 
|---|
| 552 |  | 
|---|
| 553 | return NT_STATUS_OK; | 
|---|
| 554 |  | 
|---|
| 555 | case RAW_SFILEINFO_END_OF_FILE_INFORMATION: | 
|---|
| 556 | BLOB_CHECK_MIN_SIZE(blob, 8); | 
|---|
| 557 |  | 
|---|
| 558 | st->end_of_file_info.in.size = BVAL(blob->data, 0); | 
|---|
| 559 |  | 
|---|
| 560 | return NT_STATUS_OK; | 
|---|
| 561 |  | 
|---|
| 562 | case RAW_SFILEINFO_RENAME_INFORMATION: | 
|---|
| 563 | if (!bufinfo) { | 
|---|
| 564 | return NT_STATUS_INTERNAL_ERROR; | 
|---|
| 565 | } | 
|---|
| 566 | BLOB_CHECK_MIN_SIZE(blob, 12); | 
|---|
| 567 | st->rename_information.in.overwrite = CVAL(blob->data, 0); | 
|---|
| 568 | st->rename_information.in.root_fid  = IVAL(blob->data, 4); | 
|---|
| 569 | len                                 = IVAL(blob->data, 8); | 
|---|
| 570 | ofs                                 = 12; | 
|---|
| 571 | str_blob = *blob; | 
|---|
| 572 | str_blob.length = MIN(str_blob.length, ofs+len); | 
|---|
| 573 | smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, | 
|---|
| 574 | &st->rename_information.in.new_name, | 
|---|
| 575 | STR_UNICODE); | 
|---|
| 576 | if (st->rename_information.in.new_name == NULL) { | 
|---|
| 577 | return NT_STATUS_FOOBAR; | 
|---|
| 578 | } | 
|---|
| 579 |  | 
|---|
| 580 | return NT_STATUS_OK; | 
|---|
| 581 |  | 
|---|
| 582 |  | 
|---|
| 583 | case RAW_SFILEINFO_LINK_INFORMATION: | 
|---|
| 584 | if (!bufinfo) { | 
|---|
| 585 | return NT_STATUS_INTERNAL_ERROR; | 
|---|
| 586 | } | 
|---|
| 587 | BLOB_CHECK_MIN_SIZE(blob, 20); | 
|---|
| 588 | st->link_information.in.overwrite = CVAL(blob->data, 0); | 
|---|
| 589 | st->link_information.in.root_fid  = IVAL(blob->data, 8); | 
|---|
| 590 | len                                 = IVAL(blob->data, 16); | 
|---|
| 591 | ofs                                 = 20; | 
|---|
| 592 | str_blob = *blob; | 
|---|
| 593 | str_blob.length = MIN(str_blob.length, ofs+len); | 
|---|
| 594 | smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, | 
|---|
| 595 | &st->link_information.in.new_name, | 
|---|
| 596 | STR_UNICODE); | 
|---|
| 597 | if (st->link_information.in.new_name == NULL) { | 
|---|
| 598 | return NT_STATUS_FOOBAR; | 
|---|
| 599 | } | 
|---|
| 600 |  | 
|---|
| 601 | return NT_STATUS_OK; | 
|---|
| 602 |  | 
|---|
| 603 | case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: | 
|---|
| 604 | /* SMB2 uses a different format for rename information */ | 
|---|
| 605 | if (!bufinfo) { | 
|---|
| 606 | return NT_STATUS_INTERNAL_ERROR; | 
|---|
| 607 | } | 
|---|
| 608 | BLOB_CHECK_MIN_SIZE(blob, 20); | 
|---|
| 609 | st->rename_information.in.overwrite = CVAL(blob->data, 0); | 
|---|
| 610 | st->rename_information.in.root_fid  = BVAL(blob->data, 8); | 
|---|
| 611 | len                                 = IVAL(blob->data,16); | 
|---|
| 612 | ofs                                 = 20; | 
|---|
| 613 | str_blob = *blob; | 
|---|
| 614 | str_blob.length = MIN(str_blob.length, ofs+len); | 
|---|
| 615 | smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, | 
|---|
| 616 | &st->rename_information.in.new_name, | 
|---|
| 617 | STR_UNICODE); | 
|---|
| 618 | if (st->rename_information.in.new_name == NULL) { | 
|---|
| 619 | return NT_STATUS_FOOBAR; | 
|---|
| 620 | } | 
|---|
| 621 |  | 
|---|
| 622 | return NT_STATUS_OK; | 
|---|
| 623 |  | 
|---|
| 624 | case RAW_SFILEINFO_POSITION_INFORMATION: | 
|---|
| 625 | BLOB_CHECK_MIN_SIZE(blob, 8); | 
|---|
| 626 |  | 
|---|
| 627 | st->position_information.in.position = BVAL(blob->data, 0); | 
|---|
| 628 |  | 
|---|
| 629 | return NT_STATUS_OK; | 
|---|
| 630 |  | 
|---|
| 631 | case RAW_SFILEINFO_MODE_INFORMATION: | 
|---|
| 632 | BLOB_CHECK_MIN_SIZE(blob, 4); | 
|---|
| 633 |  | 
|---|
| 634 | st->mode_information.in.mode = IVAL(blob->data, 0); | 
|---|
| 635 |  | 
|---|
| 636 | return NT_STATUS_OK; | 
|---|
| 637 |  | 
|---|
| 638 | default: | 
|---|
| 639 | return NT_STATUS_INVALID_LEVEL; | 
|---|
| 640 | } | 
|---|
| 641 |  | 
|---|
| 642 | return NT_STATUS_INVALID_LEVEL; | 
|---|
| 643 | } | 
|---|
| 644 |  | 
|---|
| 645 | /* | 
|---|
| 646 | fill a single entry in a trans2 find reply | 
|---|
| 647 | */ | 
|---|
| 648 | NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx, | 
|---|
| 649 | DATA_BLOB *blob, | 
|---|
| 650 | enum smb_search_data_level level, | 
|---|
| 651 | const union smb_search_data *file, | 
|---|
| 652 | int default_str_flags) | 
|---|
| 653 | { | 
|---|
| 654 | uint8_t *data; | 
|---|
| 655 | uint_t ofs = blob->length; | 
|---|
| 656 |  | 
|---|
| 657 | switch (level) { | 
|---|
| 658 | case RAW_SEARCH_DATA_DIRECTORY_INFO: | 
|---|
| 659 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 64)); | 
|---|
| 660 | data = blob->data + ofs; | 
|---|
| 661 | SIVAL(data,          4, file->directory_info.file_index); | 
|---|
| 662 | push_nttime(data,    8, file->directory_info.create_time); | 
|---|
| 663 | push_nttime(data,   16, file->directory_info.access_time); | 
|---|
| 664 | push_nttime(data,   24, file->directory_info.write_time); | 
|---|
| 665 | push_nttime(data,   32, file->directory_info.change_time); | 
|---|
| 666 | SBVAL(data,         40, file->directory_info.size); | 
|---|
| 667 | SBVAL(data,         48, file->directory_info.alloc_size); | 
|---|
| 668 | SIVAL(data,         56, file->directory_info.attrib); | 
|---|
| 669 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->directory_info.name.s, | 
|---|
| 670 | ofs + 60, default_str_flags, | 
|---|
| 671 | STR_TERMINATE_ASCII)); | 
|---|
| 672 | BLOB_ALIGN(blob, 8); | 
|---|
| 673 | data = blob->data + ofs; | 
|---|
| 674 | SIVAL(data,          0, blob->length - ofs); | 
|---|
| 675 | return NT_STATUS_OK; | 
|---|
| 676 |  | 
|---|
| 677 | case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: | 
|---|
| 678 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 68)); | 
|---|
| 679 | data = blob->data + ofs; | 
|---|
| 680 | SIVAL(data,          4, file->full_directory_info.file_index); | 
|---|
| 681 | push_nttime(data,    8, file->full_directory_info.create_time); | 
|---|
| 682 | push_nttime(data,   16, file->full_directory_info.access_time); | 
|---|
| 683 | push_nttime(data,   24, file->full_directory_info.write_time); | 
|---|
| 684 | push_nttime(data,   32, file->full_directory_info.change_time); | 
|---|
| 685 | SBVAL(data,         40, file->full_directory_info.size); | 
|---|
| 686 | SBVAL(data,         48, file->full_directory_info.alloc_size); | 
|---|
| 687 | SIVAL(data,         56, file->full_directory_info.attrib); | 
|---|
| 688 | SIVAL(data,         64, file->full_directory_info.ea_size); | 
|---|
| 689 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->full_directory_info.name.s, | 
|---|
| 690 | ofs + 60, default_str_flags, | 
|---|
| 691 | STR_TERMINATE_ASCII)); | 
|---|
| 692 | BLOB_ALIGN(blob, 8); | 
|---|
| 693 | data = blob->data + ofs; | 
|---|
| 694 | SIVAL(data,          0, blob->length - ofs); | 
|---|
| 695 | return NT_STATUS_OK; | 
|---|
| 696 |  | 
|---|
| 697 | case RAW_SEARCH_DATA_NAME_INFO: | 
|---|
| 698 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 12)); | 
|---|
| 699 | data = blob->data + ofs; | 
|---|
| 700 | SIVAL(data,          4, file->name_info.file_index); | 
|---|
| 701 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->name_info.name.s, | 
|---|
| 702 | ofs + 8, default_str_flags, | 
|---|
| 703 | STR_TERMINATE_ASCII)); | 
|---|
| 704 | BLOB_ALIGN(blob, 8); | 
|---|
| 705 | data = blob->data + ofs; | 
|---|
| 706 | SIVAL(data,          0, blob->length - ofs); | 
|---|
| 707 | return NT_STATUS_OK; | 
|---|
| 708 |  | 
|---|
| 709 | case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: | 
|---|
| 710 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 94)); | 
|---|
| 711 | data = blob->data + ofs; | 
|---|
| 712 | SIVAL(data,          4, file->both_directory_info.file_index); | 
|---|
| 713 | push_nttime(data,    8, file->both_directory_info.create_time); | 
|---|
| 714 | push_nttime(data,   16, file->both_directory_info.access_time); | 
|---|
| 715 | push_nttime(data,   24, file->both_directory_info.write_time); | 
|---|
| 716 | push_nttime(data,   32, file->both_directory_info.change_time); | 
|---|
| 717 | SBVAL(data,         40, file->both_directory_info.size); | 
|---|
| 718 | SBVAL(data,         48, file->both_directory_info.alloc_size); | 
|---|
| 719 | SIVAL(data,         56, file->both_directory_info.attrib); | 
|---|
| 720 | SIVAL(data,         64, file->both_directory_info.ea_size); | 
|---|
| 721 | SCVAL(data,         69, 0); /* reserved */ | 
|---|
| 722 | memset(data+70,0,24); | 
|---|
| 723 | smbsrv_blob_push_string(mem_ctx, blob, | 
|---|
| 724 | 68 + ofs, 70 + ofs, | 
|---|
| 725 | file->both_directory_info.short_name.s, | 
|---|
| 726 | 24, default_str_flags, | 
|---|
| 727 | STR_UNICODE | STR_LEN8BIT); | 
|---|
| 728 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->both_directory_info.name.s, | 
|---|
| 729 | ofs + 60, default_str_flags, | 
|---|
| 730 | STR_TERMINATE_ASCII)); | 
|---|
| 731 | BLOB_ALIGN(blob, 8); | 
|---|
| 732 | data = blob->data + ofs; | 
|---|
| 733 | SIVAL(data,          0, blob->length - ofs); | 
|---|
| 734 | return NT_STATUS_OK; | 
|---|
| 735 |  | 
|---|
| 736 | case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: | 
|---|
| 737 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 80)); | 
|---|
| 738 | data = blob->data + ofs; | 
|---|
| 739 | SIVAL(data,          4, file->id_full_directory_info.file_index); | 
|---|
| 740 | push_nttime(data,    8, file->id_full_directory_info.create_time); | 
|---|
| 741 | push_nttime(data,   16, file->id_full_directory_info.access_time); | 
|---|
| 742 | push_nttime(data,   24, file->id_full_directory_info.write_time); | 
|---|
| 743 | push_nttime(data,   32, file->id_full_directory_info.change_time); | 
|---|
| 744 | SBVAL(data,         40, file->id_full_directory_info.size); | 
|---|
| 745 | SBVAL(data,         48, file->id_full_directory_info.alloc_size); | 
|---|
| 746 | SIVAL(data,         56, file->id_full_directory_info.attrib); | 
|---|
| 747 | SIVAL(data,         64, file->id_full_directory_info.ea_size); | 
|---|
| 748 | SIVAL(data,         68, 0); /* padding */ | 
|---|
| 749 | SBVAL(data,         72, file->id_full_directory_info.file_id); | 
|---|
| 750 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->id_full_directory_info.name.s, | 
|---|
| 751 | ofs + 60, default_str_flags, | 
|---|
| 752 | STR_TERMINATE_ASCII)); | 
|---|
| 753 | BLOB_ALIGN(blob, 8); | 
|---|
| 754 | data = blob->data + ofs; | 
|---|
| 755 | SIVAL(data,          0, blob->length - ofs); | 
|---|
| 756 | return NT_STATUS_OK; | 
|---|
| 757 |  | 
|---|
| 758 | case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: | 
|---|
| 759 | BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 104)); | 
|---|
| 760 | data = blob->data + ofs; | 
|---|
| 761 | SIVAL(data,          4, file->id_both_directory_info.file_index); | 
|---|
| 762 | push_nttime(data,    8, file->id_both_directory_info.create_time); | 
|---|
| 763 | push_nttime(data,   16, file->id_both_directory_info.access_time); | 
|---|
| 764 | push_nttime(data,   24, file->id_both_directory_info.write_time); | 
|---|
| 765 | push_nttime(data,   32, file->id_both_directory_info.change_time); | 
|---|
| 766 | SBVAL(data,         40, file->id_both_directory_info.size); | 
|---|
| 767 | SBVAL(data,         48, file->id_both_directory_info.alloc_size); | 
|---|
| 768 | SIVAL(data,         56, file->id_both_directory_info.attrib); | 
|---|
| 769 | SIVAL(data,         64, file->id_both_directory_info.ea_size); | 
|---|
| 770 | SCVAL(data,         69, 0); /* reserved */ | 
|---|
| 771 | memset(data+70,0,26); | 
|---|
| 772 | smbsrv_blob_push_string(mem_ctx, blob, | 
|---|
| 773 | 68 + ofs, 70 + ofs, | 
|---|
| 774 | file->id_both_directory_info.short_name.s, | 
|---|
| 775 | 24, default_str_flags, | 
|---|
| 776 | STR_UNICODE | STR_LEN8BIT); | 
|---|
| 777 | SBVAL(data,         96, file->id_both_directory_info.file_id); | 
|---|
| 778 | BLOB_CHECK(smbsrv_blob_append_string(mem_ctx, blob, file->id_both_directory_info.name.s, | 
|---|
| 779 | ofs + 60, default_str_flags, | 
|---|
| 780 | STR_TERMINATE_ASCII)); | 
|---|
| 781 | BLOB_ALIGN(blob, 8); | 
|---|
| 782 | data = blob->data + ofs; | 
|---|
| 783 | SIVAL(data,          0, blob->length - ofs); | 
|---|
| 784 | return NT_STATUS_OK; | 
|---|
| 785 |  | 
|---|
| 786 | default: | 
|---|
| 787 | return NT_STATUS_INVALID_LEVEL; | 
|---|
| 788 | } | 
|---|
| 789 |  | 
|---|
| 790 | return NT_STATUS_INVALID_LEVEL; | 
|---|
| 791 | } | 
|---|