LCOV - code coverage report
Current view: top level - source4/smb_server - blob.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 414 462 89.6 %
Date: 2024-04-21 15:09:00 Functions: 9 9 100.0 %

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

Generated by: LCOV version 1.14