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 }