LCOV - code coverage report
Current view: top level - source4/libcli/smb2 - getinfo.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 79 87 90.8 %
Date: 2021-09-23 10:06:22 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    SMB2 client getinfo calls
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2005
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/raw/libcliraw.h"
      24             : #include "libcli/raw/raw_proto.h"
      25             : #include "libcli/smb2/smb2.h"
      26             : #include "libcli/smb2/smb2_calls.h"
      27             : 
      28             : /*
      29             :   send a getinfo request
      30             : */
      31       12378 : struct smb2_request *smb2_getinfo_send(struct smb2_tree *tree, struct smb2_getinfo *io)
      32             : {
      33             :         struct smb2_request *req;
      34             :         NTSTATUS status;
      35             :         size_t max_payload;
      36             : 
      37       12378 :         req = smb2_request_init_tree(tree, SMB2_OP_GETINFO, 0x28, true, 
      38       12378 :                                      io->in.input_buffer.length);
      39       12378 :         if (req == NULL) return NULL;
      40             : 
      41       12378 :         SCVAL(req->out.body, 0x02, io->in.info_type);
      42       12378 :         SCVAL(req->out.body, 0x03, io->in.info_class);
      43       12378 :         SIVAL(req->out.body, 0x04, io->in.output_buffer_length);
      44             :         /*
      45             :          * uint16_t input_buffer_offset
      46             :          * uint16_t reserved
      47             :          * uint32_t input_buffer_length
      48             :          *
      49             :          * We use smb2_push_o32s32_blob() which would
      50             :          * expect uint32_t offset, uint32_t length.
      51             :          *
      52             :          * Everything is little endian, we can just
      53             :          * overwrite the reserved field later.
      54             :          */
      55       12378 :         SIVAL(req->out.body, 0x10, io->in.additional_information);
      56       12378 :         SIVAL(req->out.body, 0x14, io->in.getinfo_flags);
      57       12378 :         smb2_push_handle(req->out.body+0x18, &io->in.file.handle);
      58             : 
      59             :         /* this blob is used for quota queries */
      60       12378 :         status = smb2_push_o32s32_blob(&req->out, 0x08, io->in.input_buffer);
      61       12378 :         if (!NT_STATUS_IS_OK(status)) {
      62           0 :                 talloc_free(req);
      63           0 :                 return NULL;
      64             :         }
      65       12378 :         SSVAL(req->out.body, 0x0C, io->in.reserved);
      66             : 
      67       12378 :         max_payload = MAX(io->in.output_buffer_length, io->in.input_buffer.length);
      68       12378 :         req->credit_charge = (MAX(max_payload, 1) - 1)/ 65536 + 1;
      69             : 
      70       12378 :         smb2_transport_send(req);
      71             : 
      72       12378 :         return req;
      73             : }
      74             : 
      75             : 
      76             : /*
      77             :   recv a getinfo reply
      78             : */
      79       12372 : NTSTATUS smb2_getinfo_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
      80             :                            struct smb2_getinfo *io)
      81             : {
      82             :         NTSTATUS status;
      83             : 
      84       24736 :         if (!smb2_request_receive(req) || 
      85       12364 :             smb2_request_is_error(req)) {
      86        2082 :                 return smb2_request_destroy(req);
      87             :         }
      88             : 
      89       10290 :         SMB2_CHECK_PACKET_RECV(req, 0x08, true);
      90             : 
      91       10290 :         status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob);
      92       10290 :         if (!NT_STATUS_IS_OK(status)) {
      93           0 :                 return status;
      94             :         }
      95             : 
      96       10290 :         return smb2_request_destroy(req);
      97             : }
      98             : 
      99             : /*
     100             :   sync getinfo request
     101             : */
     102        2297 : NTSTATUS smb2_getinfo(struct smb2_tree *tree, TALLOC_CTX *mem_ctx,
     103             :                       struct smb2_getinfo *io)
     104             : {
     105        2297 :         struct smb2_request *req = smb2_getinfo_send(tree, io);
     106        2297 :         return smb2_getinfo_recv(req, mem_ctx, io);
     107             : }
     108             : 
     109             : 
     110             : /*
     111             :   map a generic info level to a SMB2 info level
     112             : */
     113       16194 : uint16_t smb2_getinfo_map_level(uint16_t level, uint8_t info_class)
     114             : {
     115       16194 :         if (info_class == SMB2_0_INFO_FILE &&
     116           0 :             level == RAW_FILEINFO_SEC_DESC) {
     117        8642 :                 return SMB2_0_INFO_SECURITY;
     118             :         }
     119        7552 :         if ((level & 0xFF) == info_class) {
     120        1045 :                 return level;
     121        6507 :         } else if (level > 1000) {
     122        6507 :                 return ((level-1000)<<8) | info_class;
     123             :         }
     124           0 :         DEBUG(0,("Unable to map SMB2 info level 0x%04x of class %d\n",
     125             :                  level, info_class));
     126           0 :         return 0;       
     127             : }
     128             : 
     129             : /*
     130             :   level specific getinfo call - async send
     131             : */
     132        9723 : struct smb2_request *smb2_getinfo_file_send(struct smb2_tree *tree, union smb_fileinfo *io)
     133             : {
     134             :         struct smb2_getinfo b;
     135        9723 :         uint16_t smb2_level = smb2_getinfo_map_level(
     136        9723 :                 io->generic.level, SMB2_0_INFO_FILE);
     137             :         
     138        9723 :         if (smb2_level == 0) {
     139           0 :                 return NULL;
     140             :         }
     141             : 
     142        9723 :         ZERO_STRUCT(b);
     143        9723 :         b.in.info_type            = smb2_level & 0xFF;
     144        9723 :         b.in.info_class           = smb2_level >> 8;
     145        9723 :         b.in.output_buffer_length = 0x10000;
     146        9723 :         b.in.input_buffer         = data_blob_null;
     147        9723 :         b.in.file.handle          = io->generic.in.file.handle;
     148             : 
     149        9723 :         if (io->generic.level == RAW_FILEINFO_SEC_DESC) {
     150        4034 :                 b.in.additional_information = io->query_secdesc.in.secinfo_flags;
     151             :         }
     152        9723 :         if (io->generic.level == RAW_FILEINFO_SMB2_ALL_EAS) {
     153          14 :                 b.in.getinfo_flags = io->all_eas.in.continue_flags;
     154             :         }
     155             : 
     156        9723 :         return smb2_getinfo_send(tree, &b);
     157             : }
     158             : 
     159             : /*
     160             :   recv a getinfo reply and parse the level info
     161             : */
     162        9723 : NTSTATUS smb2_getinfo_file_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
     163             :                                 union smb_fileinfo *io)
     164             : {
     165             :         struct smb2_getinfo b;
     166             :         NTSTATUS status;
     167             : 
     168        9723 :         status = smb2_getinfo_recv(req, mem_ctx, &b);
     169        9723 :         NT_STATUS_NOT_OK_RETURN(status);
     170             : 
     171        9584 :         status = smb_raw_fileinfo_passthru_parse(&b.out.blob, mem_ctx, io->generic.level, io);
     172        9584 :         data_blob_free(&b.out.blob);
     173             : 
     174        9584 :         return status;
     175             : }
     176             : 
     177             : /*
     178             :   level specific getinfo call
     179             : */
     180        9723 : NTSTATUS smb2_getinfo_file(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, 
     181             :                            union smb_fileinfo *io)
     182             : {
     183        9723 :         struct smb2_request *req = smb2_getinfo_file_send(tree, io);
     184        9723 :         return smb2_getinfo_file_recv(req, mem_ctx, io);
     185             : }
     186             : 
     187             : 
     188             : /*
     189             :   level specific getinfo call - async send
     190             : */
     191         346 : struct smb2_request *smb2_getinfo_fs_send(struct smb2_tree *tree, union smb_fsinfo *io)
     192             : {
     193             :         struct smb2_getinfo b;
     194         346 :         uint16_t smb2_level = smb2_getinfo_map_level(
     195         346 :                 io->generic.level, SMB2_0_INFO_FILESYSTEM);
     196             :         
     197         346 :         if (smb2_level == 0) {
     198           0 :                 return NULL;
     199             :         }
     200             :         
     201         346 :         ZERO_STRUCT(b);
     202         346 :         b.in.output_buffer_length = 0x10000;
     203         346 :         b.in.file.handle          = io->generic.handle;
     204         346 :         b.in.info_type            = smb2_level & 0xFF;
     205         346 :         b.in.info_class           = smb2_level >> 8;
     206             : 
     207         346 :         return smb2_getinfo_send(tree, &b);
     208             : }
     209             : 
     210             : /*
     211             :   recv a getinfo reply and parse the level info
     212             : */
     213         346 : NTSTATUS smb2_getinfo_fs_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
     214             :                                 union smb_fsinfo *io)
     215             : {
     216         346 :         struct smb2_getinfo b = {
     217             :                 .in = {0},
     218             :         };
     219             :         NTSTATUS status;
     220             : 
     221         346 :         status = smb2_getinfo_recv(req, mem_ctx, &b);
     222         346 :         NT_STATUS_NOT_OK_RETURN(status);
     223             : 
     224         342 :         status = smb_raw_fsinfo_passthru_parse(b.out.blob, mem_ctx, io->generic.level, io);
     225         342 :         data_blob_free(&b.out.blob);
     226             : 
     227         342 :         return status;
     228             : }
     229             : 
     230             : /*
     231             :   level specific getinfo call
     232             : */
     233         346 : NTSTATUS smb2_getinfo_fs(struct smb2_tree *tree, TALLOC_CTX *mem_ctx, 
     234             :                            union smb_fsinfo *io)
     235             : {
     236         346 :         struct smb2_request *req = smb2_getinfo_fs_send(tree, io);
     237         346 :         return smb2_getinfo_fs_recv(req, mem_ctx, io);
     238             : }
     239             : 

Generated by: LCOV version 1.13