| 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 | }
|
|---|