1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 #include <sys/types.h>
27 #include <sys/sid.h>
28 #include <sys/priv_names.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <smbsrv/smb_idmap.h>
32 #include <smbsrv/smb_kproto.h>
33 #include <smbsrv/smb_token.h>
34
35 smb_sdrc_t
smb_pre_session_setup_andx(smb_request_t * sr)36 smb_pre_session_setup_andx(smb_request_t *sr)
37 {
38 smb_arg_sessionsetup_t *sinfo;
39 char *native_os;
40 char *native_lm;
41 int rc = 0;
42
43 sinfo = smb_srm_zalloc(sr, sizeof (smb_arg_sessionsetup_t));
44 sr->sr_ssetup = sinfo;
45
46 /*
47 * Enforce the minimum word count seen in the old protocol,
48 * to make sure we have enough to decode the common stuff.
49 * Further wcnt checks below.
50 */
51 if (sr->smb_wct < 10) {
52 rc = -1;
53 goto done;
54 }
55
56 /*
57 * Parse common part of SMB session setup.
58 * skip: vcnumber(2), sesskey(4)
59 */
60 rc = smbsr_decode_vwv(sr, "b.www6.",
61 &sr->andx_com, &sr->andx_off,
62 &sinfo->ssi_maxbufsize, &sinfo->ssi_maxmpxcount);
63 if (rc != 0)
64 goto done;
65
66 if (sr->session->dialect < NT_LM_0_12) {
67
68 sinfo->ssi_type = SMB_SSNSETUP_PRE_NTLM012;
69 sinfo->ssi_capabilities = 0;
70
71 rc = smbsr_decode_vwv(sr, "w4.",
72 &sinfo->ssi_lmpwlen);
73 if (rc != 0)
74 goto done;
75
76 sinfo->ssi_lmpwd = smb_srm_zalloc(sr, sinfo->ssi_lmpwlen + 1);
77 rc = smbsr_decode_data(sr, "%#c", sr, sinfo->ssi_lmpwlen,
78 sinfo->ssi_lmpwd);
79 if (rc != 0)
80 goto done;
81
82 sinfo->ssi_lmpwd[sinfo->ssi_lmpwlen] = 0;
83
84 if (smbsr_decode_data(sr, "%u", sr, &sinfo->ssi_user) != 0)
85 sinfo->ssi_user = "";
86
87 if (smbsr_decode_data(sr, "%u", sr, &sinfo->ssi_domain) != 0)
88 sinfo->ssi_domain = "";
89
90 goto part2;
91 }
92
93 /*
94 * We have dialect >= NT_LM_0_12
95 */
96 if (sr->smb_wct == 13) {
97 /* Old style (non-extended) request. */
98 sinfo->ssi_type = SMB_SSNSETUP_NTLM012_NOEXT;
99
100 rc = smbsr_decode_vwv(sr, "ww4.l",
101 &sinfo->ssi_lmpwlen,
102 &sinfo->ssi_ntpwlen,
103 &sinfo->ssi_capabilities);
104 if (rc != 0)
105 goto done;
106
107 /* paranoid: ignore cap. ext. sec. here */
108 sinfo->ssi_capabilities &= ~CAP_EXTENDED_SECURITY;
109
110 sinfo->ssi_lmpwd = smb_srm_zalloc(sr, sinfo->ssi_lmpwlen + 1);
111 sinfo->ssi_ntpwd = smb_srm_zalloc(sr, sinfo->ssi_ntpwlen + 1);
112
113 rc = smbsr_decode_data(sr, "%#c#cuu", sr,
114 sinfo->ssi_lmpwlen, sinfo->ssi_lmpwd,
115 sinfo->ssi_ntpwlen, sinfo->ssi_ntpwd,
116 &sinfo->ssi_user, &sinfo->ssi_domain);
117 if (rc != 0)
118 goto done;
119
120 sinfo->ssi_lmpwd[sinfo->ssi_lmpwlen] = 0;
121 sinfo->ssi_ntpwd[sinfo->ssi_ntpwlen] = 0;
122
123 goto part2;
124 }
125
126 if (sr->smb_wct == 12) {
127 /* New style (extended) request. */
128 sinfo->ssi_type = SMB_SSNSETUP_NTLM012_EXTSEC;
129
130 rc = smbsr_decode_vwv(sr, "w4.l",
131 &sinfo->ssi_iseclen,
132 &sinfo->ssi_capabilities);
133 if (rc != 0)
134 goto done;
135
136 if ((sinfo->ssi_capabilities & CAP_EXTENDED_SECURITY) == 0) {
137 rc = -1;
138 goto done;
139 }
140
141 sinfo->ssi_isecblob = smb_srm_zalloc(sr, sinfo->ssi_iseclen);
142 rc = smbsr_decode_data(sr, "%#c", sr,
143 sinfo->ssi_iseclen, sinfo->ssi_isecblob);
144 if (rc != 0)
145 goto done;
146
147 goto part2;
148 }
149
150 /* Invalid message */
151 rc = -1;
152 goto done;
153
154 part2:
155 /*
156 * Get the "Native OS" and "Native LanMan" strings.
157 * These are not critical to protocol function, so
158 * if we can't parse them, just guess "NT".
159 * These strings are free'd with the sr.
160 *
161 * In NTLM 0.12, the padding between the Native OS and Native LM
162 * is a bit strange. On NT4.0, there is a 2 byte pad between the
163 * OS (Windows NT 1381) and LM (Windows NT 4.0). On Windows 2000,
164 * there is no padding between the OS (Windows 2000 2195) and LM
165 * (Windows 2000 5.0). If the padding is removed from the decode
166 * string the NT4.0 LM comes out as an empty string. So if the
167 * client's native OS is Win NT, assume extra padding.
168 */
169 rc = smbsr_decode_data(sr, "%u", sr, &native_os);
170 if (rc != 0 || native_os == NULL)
171 sinfo->ssi_native_os = NATIVE_OS_WINNT;
172 else
173 sinfo->ssi_native_os = smbnative_os_value(native_os);
174
175 if (sinfo->ssi_native_os == NATIVE_OS_WINNT)
176 rc = smbsr_decode_data(sr, "%,u", sr, &native_lm);
177 else
178 rc = smbsr_decode_data(sr, "%u", sr, &native_lm);
179 if (rc != 0 || native_lm == NULL)
180 sinfo->ssi_native_lm = NATIVE_LM_NT;
181 else
182 sinfo->ssi_native_lm = smbnative_lm_value(native_lm);
183 rc = 0;
184
185 done:
186 if (rc != 0) {
187 cmn_err(CE_NOTE,
188 "SmbSessonSetupX: client %s invalid request",
189 sr->session->ip_addr_str);
190 }
191
192 DTRACE_SMB_START(op__SessionSetupX, smb_request_t *, sr);
193 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
194 }
195
196 void
smb_post_session_setup_andx(smb_request_t * sr)197 smb_post_session_setup_andx(smb_request_t *sr)
198 {
199 smb_arg_sessionsetup_t *sinfo = sr->sr_ssetup;
200
201 DTRACE_SMB_DONE(op__SessionSetupX, smb_request_t *, sr);
202
203 if (sinfo->ssi_lmpwd != NULL)
204 bzero(sinfo->ssi_lmpwd, sinfo->ssi_lmpwlen);
205
206 if (sinfo->ssi_ntpwd != NULL)
207 bzero(sinfo->ssi_ntpwd, sinfo->ssi_ntpwlen);
208 }
209
210 /*
211 *
212 * NT systems use different native OS and native LanMan values dependent on
213 * whether they are acting as a client or a server. NT 4.0 server responds
214 * with the following values:
215 *
216 * NativeOS: Windows NT 4.0
217 * NativeLM: NT LAN Manager 4.0
218 */
219 smb_sdrc_t
smb_com_session_setup_andx(smb_request_t * sr)220 smb_com_session_setup_andx(smb_request_t *sr)
221 {
222 smb_arg_sessionsetup_t *sinfo = sr->sr_ssetup;
223 uint32_t status;
224 uint16_t action;
225 int rc;
226
227 /*
228 * Some stuff we do only in the first in a (possible)
229 * sequence of session setup requests.
230 */
231 if (sinfo->ssi_type != SMB_SSNSETUP_NTLM012_EXTSEC ||
232 sr->smb_uid == 0 || sr->smb_uid == 0xFFFF) {
233
234 /* This is a first (or only) call */
235 sr->session->smb_msg_size = sinfo->ssi_maxbufsize;
236 sr->session->smb_max_mpx = sinfo->ssi_maxmpxcount;
237 sr->session->capabilities = sinfo->ssi_capabilities;
238 sr->session->native_os = sinfo->ssi_native_os;
239 sr->session->native_lm = sinfo->ssi_native_lm;
240 }
241
242 /* RejectUnencryptedAccess precludes SMB1 access */
243 if (sr->sr_server->sv_cfg.skc_encrypt == SMB_CONFIG_REQUIRED) {
244 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
245 ERRDOS, ERROR_ACCESS_DENIED);
246 return (SDRC_ERROR);
247 }
248
249 /*
250 * The "meat" of authentication happens here.
251 */
252 if (sinfo->ssi_type == SMB_SSNSETUP_NTLM012_EXTSEC)
253 status = smb_authenticate_ext(sr);
254 else
255 status = smb_authenticate_old(sr);
256
257 switch (status) {
258
259 case NT_STATUS_SUCCESS:
260 break;
261
262 /*
263 * This is not really an error, but tells the client
264 * it should send another session setup request.
265 */
266 case NT_STATUS_MORE_PROCESSING_REQUIRED:
267 smbsr_error(sr, status, 0, 0);
268 break;
269
270 case NT_STATUS_ACCESS_DENIED:
271 smbsr_error(sr, status, ERRDOS, ERROR_ACCESS_DENIED);
272 return (SDRC_ERROR);
273
274 case NT_STATUS_TOO_MANY_SESSIONS:
275 smbsr_error(sr, status, ERRSRV, ERRtoomanyuids);
276 return (SDRC_ERROR);
277
278 case NT_STATUS_NO_LOGON_SERVERS:
279 smbsr_error(sr, status, ERRDOS, ERROR_NO_LOGON_SERVERS);
280 return (SDRC_ERROR);
281
282 case NT_STATUS_NETLOGON_NOT_STARTED:
283 smbsr_error(sr, status, ERRDOS, ERROR_NETLOGON_NOT_STARTED);
284 return (SDRC_ERROR);
285
286 case NT_STATUS_USER_SESSION_DELETED:
287 smbsr_error(sr, status, ERRSRV, ERRbaduid);
288 return (SDRC_ERROR);
289
290 case NT_STATUS_INSUFF_SERVER_RESOURCES:
291 smbsr_error(sr, status, ERRSRV, ERRnoresource);
292 return (SDRC_ERROR);
293
294 case NT_STATUS_INTERNAL_ERROR:
295 default:
296 smbsr_error(sr, status, ERRSRV, ERRsrverror);
297 return (SDRC_ERROR);
298 }
299
300 action = SMB_USER_IS_GUEST(sr->uid_user) ? 1 : 0;
301
302 switch (sinfo->ssi_type) {
303
304 default:
305 case SMB_SSNSETUP_PRE_NTLM012:
306 case SMB_SSNSETUP_NTLM012_NOEXT:
307
308 rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu",
309 3,
310 sr->andx_com,
311 -1, /* andx_off */
312 action,
313 VAR_BCC,
314 sr,
315 sr->sr_cfg->skc_native_os,
316 sr->sr_cfg->skc_native_lm,
317 sr->sr_cfg->skc_nbdomain);
318 break;
319
320 case SMB_SSNSETUP_NTLM012_EXTSEC:
321
322 rc = smbsr_encode_result(sr, 4, VAR_BCC, "bb.wwww%#cuuu",
323 4,
324 sr->andx_com,
325 -1, /* andx_off */
326 action,
327 sinfo->ssi_oseclen,
328 VAR_BCC,
329 sr,
330 sinfo->ssi_oseclen,
331 sinfo->ssi_osecblob,
332 sr->sr_cfg->skc_native_os,
333 sr->sr_cfg->skc_native_lm,
334 sr->sr_cfg->skc_nbdomain);
335 break;
336 }
337
338 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
339 }
340