1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 /*
  17  * Dispatch function for SMB2_QUERY_INFO
  18  */
  19 
  20 #include <smbsrv/smb2_kproto.h>
  21 #include <smbsrv/smb_fsops.h>
  22 #include <smbsrv/ntifs.h>
  23 
  24 smb_sdrc_t
  25 smb2_query_info(smb_request_t *sr)
  26 {
  27         smb_queryinfo_t *qi;
  28         uint16_t StructSize;
  29         uint32_t oBufLength;
  30         uint16_t iBufOffset;
  31         uint32_t iBufLength;
  32         smb2fid_t smb2fid;
  33         uint16_t DataOff;
  34         uint32_t status;
  35         smb_sdrc_t sdrc = SDRC_SUCCESS;
  36         int rc = 0;
  37 
  38         qi = kmem_zalloc(sizeof (*qi), KM_SLEEP);
  39 
  40         /*
  41          * SMB2 Query Info request
  42          */
  43         rc = smb_mbc_decodef(
  44             &sr->smb_data, "wbblw..lllqq",
  45             &StructSize,            /* w */
  46             &qi->qi_InfoType,            /* b */
  47             &qi->qi_InfoClass,           /* b */
  48             &oBufLength,            /* l */
  49             &iBufOffset,            /* w */
  50             /* reserved                   .. */
  51             &iBufLength,            /* l */
  52             &qi->qi_AddlInfo,            /* l */
  53             &qi->qi_Flags,               /* l */
  54             &smb2fid.persistent,    /* q */
  55             &smb2fid.temporal);             /* q */
  56         if (rc || StructSize != 41) {
  57                 sdrc = SDRC_ERROR;
  58                 goto out;
  59         }
  60 
  61         status = smb2sr_lookup_fid(sr, &smb2fid);
  62         if (status) {
  63                 smb2sr_put_error(sr, status);
  64                 goto out;
  65         }
  66 
  67         if (oBufLength > smb2_max_trans)
  68                 oBufLength = smb2_max_trans;
  69 
  70         /*
  71          * If there's an input buffer, setup a shadow.
  72          */
  73         if (iBufLength) {
  74                 rc = MBC_SHADOW_CHAIN(&qi->in_data, &sr->smb_data,
  75                     sr->smb2_cmd_hdr + iBufOffset, iBufLength);
  76                 if (rc) {
  77                         smb2sr_put_error(sr, NT_STATUS_INVALID_PARAMETER);
  78                         goto out;
  79                 }
  80         }
  81 
  82         sr->raw_data.max_bytes = oBufLength;
  83 
  84         switch (qi->qi_InfoType) {
  85         case SMB2_0_INFO_FILE:
  86                 status = smb2_qinfo_file(sr, qi);
  87                 break;
  88         case SMB2_0_INFO_FILESYSTEM:
  89                 status = smb2_qinfo_fs(sr, qi);
  90                 break;
  91         case SMB2_0_INFO_SECURITY:
  92                 status = smb2_qinfo_sec(sr, qi);
  93                 break;
  94         case SMB2_0_INFO_QUOTA:
  95                 status = smb2_qinfo_quota(sr, qi);
  96                 break;
  97         default:
  98                 status = NT_STATUS_INVALID_PARAMETER;
  99                 break;
 100         }
 101 
 102         switch (status) {
 103 
 104         case 0: /* success */
 105                 break;
 106 
 107         case NT_STATUS_BUFFER_OVERFLOW:
 108                 /* Not really an error, per se.  Advisory. */
 109                 sr->smb2_status = status;
 110                 break;
 111 
 112         case NT_STATUS_BUFFER_TOO_SMALL:
 113         case NT_STATUS_INFO_LENGTH_MISMATCH:
 114                 /*
 115                  * These are special, per. [MS-SMB2] 3.2.5.17
 116                  * The error data is a 4-byte count of the size
 117                  * required to successfully query the data.
 118                  * That error data is built by the functions
 119                  * that returns one of these errors.
 120                  */
 121                 smb2sr_put_error_data(sr, status, &sr->raw_data);
 122                 goto out;
 123 
 124         default:
 125                 smb2sr_put_error(sr, status);
 126                 goto out;
 127         }
 128 
 129         /*
 130          * SMB2 Query Info reply
 131          */
 132         DataOff = SMB2_HDR_SIZE + 8;
 133         oBufLength = MBC_LENGTH(&sr->raw_data);
 134         rc = smb_mbc_encodef(
 135             &sr->reply, "wwlC",
 136             9,  /* StructSize */        /* w */
 137             DataOff,                    /* w */
 138             oBufLength,                 /* l */
 139             &sr->raw_data);              /* C */
 140         if (rc)
 141                 sdrc = SDRC_ERROR;
 142 
 143 out:
 144         kmem_free(qi, sizeof (*qi));
 145 
 146         return (sdrc);
 147 }
 | 
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 /*
  17  * Dispatch function for SMB2_QUERY_INFO
  18  */
  19 
  20 #include <smbsrv/smb2_kproto.h>
  21 #include <smbsrv/smb_fsops.h>
  22 #include <smbsrv/ntifs.h>
  23 
  24 smb_sdrc_t
  25 smb2_query_info(smb_request_t *sr)
  26 {
  27         smb_queryinfo_t *qi;
  28         uint16_t StructSize;
  29         uint32_t oBufLength;
  30         uint16_t iBufOffset;
  31         uint32_t iBufLength;
  32         smb2fid_t smb2fid;
  33         uint16_t DataOff;
  34         uint32_t status;
  35         int rc = 0;
  36 
  37         qi = smb_srm_zalloc(sr, sizeof (*qi));
  38 
  39         /*
  40          * SMB2 Query Info request
  41          */
  42         rc = smb_mbc_decodef(
  43             &sr->smb_data, "wbblw..lllqq",
  44             &StructSize,            /* w */
  45             &qi->qi_InfoType,            /* b */
  46             &qi->qi_InfoClass,           /* b */
  47             &oBufLength,            /* l */
  48             &iBufOffset,            /* w */
  49             /* reserved                   .. */
  50             &iBufLength,            /* l */
  51             &qi->qi_AddlInfo,            /* l */
  52             &qi->qi_Flags,               /* l */
  53             &smb2fid.persistent,    /* q */
  54             &smb2fid.temporal);             /* q */
  55         if (rc || StructSize != 41)
  56                 return (SDRC_ERROR);
  57 
  58         /*
  59          * If there's an input buffer, setup a shadow.
  60          */
  61         if (iBufLength) {
  62                 rc = MBC_SHADOW_CHAIN(&qi->in_data, &sr->smb_data,
  63                     sr->smb2_cmd_hdr + iBufOffset, iBufLength);
  64                 if (rc) {
  65                         return (SDRC_ERROR);
  66                 }
  67         }
  68 
  69         if (oBufLength > smb2_max_trans)
  70                 oBufLength = smb2_max_trans;
  71         sr->raw_data.max_bytes = oBufLength;
  72 
  73         status = smb2sr_lookup_fid(sr, &smb2fid);
  74         DTRACE_SMB2_START(op__QueryInfo, smb_request_t *, sr);
  75 
  76         if (status)
  77                 goto errout;
  78 
  79         switch (qi->qi_InfoType) {
  80         case SMB2_0_INFO_FILE:
  81                 status = smb2_qinfo_file(sr, qi);
  82                 break;
  83         case SMB2_0_INFO_FILESYSTEM:
  84                 status = smb2_qinfo_fs(sr, qi);
  85                 break;
  86         case SMB2_0_INFO_SECURITY:
  87                 status = smb2_qinfo_sec(sr, qi);
  88                 break;
  89         case SMB2_0_INFO_QUOTA:
  90                 status = smb2_qinfo_quota(sr, qi);
  91                 break;
  92         default:
  93                 status = NT_STATUS_INVALID_PARAMETER;
  94                 break;
  95         }
  96 
  97 errout:
  98         sr->smb2_status = status;
  99         DTRACE_SMB2_DONE(op__QueryInfo, smb_request_t *, sr);
 100 
 101         switch (status) {
 102 
 103         case 0: /* success */
 104                 break;
 105 
 106         case NT_STATUS_BUFFER_OVERFLOW:
 107                 /* Not really an error, per se.  Advisory. */
 108                 break;
 109 
 110         case NT_STATUS_BUFFER_TOO_SMALL:
 111         case NT_STATUS_INFO_LENGTH_MISMATCH:
 112                 /*
 113                  * These are special, per. [MS-SMB2] 3.2.5.17
 114                  * The error data is a 4-byte count of the size
 115                  * required to successfully query the data.
 116                  * That error data is built by the functions
 117                  * that returns one of these errors.
 118                  */
 119                 smb2sr_put_error_data(sr, status, &sr->raw_data);
 120                 return (SDRC_SUCCESS);
 121 
 122         default:
 123                 smb2sr_put_error(sr, status);
 124                 return (SDRC_SUCCESS);
 125         }
 126 
 127         /*
 128          * SMB2 Query Info reply
 129          */
 130         DataOff = SMB2_HDR_SIZE + 8;
 131         oBufLength = MBC_LENGTH(&sr->raw_data);
 132         rc = smb_mbc_encodef(
 133             &sr->reply, "wwlC",
 134             9,  /* StructSize */        /* w */
 135             DataOff,                    /* w */
 136             oBufLength,                 /* l */
 137             &sr->raw_data);              /* C */
 138         if (rc)
 139                 sr->smb2_status = NT_STATUS_INTERNAL_ERROR;
 140 
 141         return (SDRC_SUCCESS);
 142 }
 |