xref: /titanic_51/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c (revision 12b65585e720714b31036daaa2b30eb76014048e)
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 2014 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
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_2(op__SessionSetupX__start, smb_request_t *, sr,
193 	    smb_arg_sessionsetup_t, sinfo);
194 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
195 }
196 
197 void
198 smb_post_session_setup_andx(smb_request_t *sr)
199 {
200 	smb_arg_sessionsetup_t	*sinfo = sr->sr_ssetup;
201 
202 	DTRACE_SMB_2(op__SessionSetupX__done, smb_request_t *, sr,
203 	    smb_arg_sessionsetup_t, sinfo);
204 
205 	if (sinfo->ssi_lmpwd != NULL)
206 		bzero(sinfo->ssi_lmpwd, sinfo->ssi_lmpwlen);
207 
208 	if (sinfo->ssi_ntpwd != NULL)
209 		bzero(sinfo->ssi_ntpwd, sinfo->ssi_ntpwlen);
210 }
211 
212 /*
213  *
214  * NT systems use different native OS and native LanMan values dependent on
215  * whether they are acting as a client or a server.  NT 4.0 server responds
216  * with the following values:
217  *
218  *      NativeOS:       Windows NT 4.0
219  *      NativeLM:       NT LAN Manager 4.0
220  */
221 smb_sdrc_t
222 smb_com_session_setup_andx(smb_request_t *sr)
223 {
224 	smb_arg_sessionsetup_t	*sinfo = sr->sr_ssetup;
225 	uint32_t		status;
226 	uint16_t		action;
227 	int			rc;
228 
229 	/*
230 	 * Some stuff we do only in the first in a (possible)
231 	 * sequence of session setup requests.
232 	 */
233 	if (sinfo->ssi_type != SMB_SSNSETUP_NTLM012_EXTSEC ||
234 	    sr->smb_uid == 0 || sr->smb_uid == 0xFFFF) {
235 
236 		/* This is a first (or only) call */
237 		sr->session->smb_msg_size = sinfo->ssi_maxbufsize;
238 		sr->session->smb_max_mpx = sinfo->ssi_maxmpxcount;
239 		sr->session->capabilities = sinfo->ssi_capabilities;
240 
241 		if (!smb_oplock_levelII)
242 			sr->session->capabilities &= ~CAP_LEVEL_II_OPLOCKS;
243 
244 		sr->session->native_os = sinfo->ssi_native_os;
245 		sr->session->native_lm = sinfo->ssi_native_lm;
246 	}
247 
248 	/*
249 	 * The "meat" of authentication happens here.
250 	 */
251 	if (sinfo->ssi_type == SMB_SSNSETUP_NTLM012_EXTSEC)
252 		status = smb_authenticate_ext(sr);
253 	else
254 		status = smb_authenticate_old(sr);
255 
256 	switch (status) {
257 
258 	case NT_STATUS_SUCCESS:
259 		break;
260 
261 	/*
262 	 * This is not really an error, but tells the client
263 	 * it should send another session setup request.
264 	 */
265 	case NT_STATUS_MORE_PROCESSING_REQUIRED:
266 		smbsr_error(sr, status, 0, 0);
267 		break;
268 
269 	case NT_STATUS_ACCESS_DENIED:
270 		smbsr_error(sr, status, ERRDOS, ERROR_ACCESS_DENIED);
271 		return (SDRC_ERROR);
272 
273 	case NT_STATUS_TOO_MANY_SESSIONS:
274 		smbsr_error(sr, status, ERRSRV, ERRtoomanyuids);
275 		return (SDRC_ERROR);
276 
277 	case NT_STATUS_NO_LOGON_SERVERS:
278 		smbsr_error(sr, status, ERRDOS, ERROR_NO_LOGON_SERVERS);
279 		return (SDRC_ERROR);
280 
281 	case NT_STATUS_NETLOGON_NOT_STARTED:
282 		smbsr_error(sr, status, ERRDOS, ERROR_NETLOGON_NOT_STARTED);
283 		return (SDRC_ERROR);
284 
285 	case NT_STATUS_USER_SESSION_DELETED:
286 		smbsr_error(sr, status, ERRSRV, ERRbaduid);
287 		return (SDRC_ERROR);
288 
289 	case NT_STATUS_INSUFF_SERVER_RESOURCES:
290 		smbsr_error(sr, status, ERRSRV, ERRnoresource);
291 		return (SDRC_ERROR);
292 
293 	case NT_STATUS_INTERNAL_ERROR:
294 	default:
295 		smbsr_error(sr, status, ERRSRV, ERRsrverror);
296 		return (SDRC_ERROR);
297 	}
298 
299 	action = SMB_USER_IS_GUEST(sr->uid_user) ? 1 : 0;
300 
301 	switch (sinfo->ssi_type) {
302 
303 	default:
304 	case SMB_SSNSETUP_PRE_NTLM012:
305 	case SMB_SSNSETUP_NTLM012_NOEXT:
306 
307 		rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu",
308 		    3,
309 		    sr->andx_com,
310 		    -1,			/* andx_off */
311 		    action,
312 		    VAR_BCC,
313 		    sr,
314 		    sr->sr_cfg->skc_native_os,
315 		    sr->sr_cfg->skc_native_lm,
316 		    sr->sr_cfg->skc_nbdomain);
317 		break;
318 
319 	case SMB_SSNSETUP_NTLM012_EXTSEC:
320 
321 		rc = smbsr_encode_result(sr, 4, VAR_BCC, "bb.wwww%#cuuu",
322 		    4,
323 		    sr->andx_com,
324 		    -1,			/* andx_off */
325 		    action,
326 		    sinfo->ssi_oseclen,
327 		    VAR_BCC,
328 		    sr,
329 		    sinfo->ssi_oseclen,
330 		    sinfo->ssi_osecblob,
331 		    sr->sr_cfg->skc_native_os,
332 		    sr->sr_cfg->skc_native_lm,
333 		    sr->sr_cfg->skc_nbdomain);
334 		break;
335 	}
336 
337 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
338 }
339