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