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