1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw /*
22148c5f43SAlan Wright  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2393bc28dbSGordon Ross  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw #include <sys/types.h>
27148c5f43SAlan Wright #include <sys/sid.h>
28148c5f43SAlan Wright #include <sys/priv_names.h>
29da6c28aaSamw #include <sys/socket.h>
30da6c28aaSamw #include <netinet/in.h>
31148c5f43SAlan Wright #include <smbsrv/smb_idmap.h>
32bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
33da6c28aaSamw #include <smbsrv/smb_token.h>
34da6c28aaSamw 
357b59d02dSjb smb_sdrc_t
smb_pre_session_setup_andx(smb_request_t * sr)36faa1795aSjb smb_pre_session_setup_andx(smb_request_t *sr)
37faa1795aSjb {
38148c5f43SAlan Wright 	smb_arg_sessionsetup_t	*sinfo;
39148c5f43SAlan Wright 	char			*native_os;
40148c5f43SAlan Wright 	char			*native_lm;
41148c5f43SAlan Wright 	int			rc = 0;
427f667e74Sjose borrego 
43148c5f43SAlan Wright 	sinfo = smb_srm_zalloc(sr, sizeof (smb_arg_sessionsetup_t));
44148c5f43SAlan Wright 	sr->sr_ssetup = sinfo;
45da6c28aaSamw 
4612b65585SGordon Ross 	/*
4712b65585SGordon Ross 	 * Enforce the minimum word count seen in the old protocol,
4812b65585SGordon Ross 	 * to make sure we have enough to decode the common stuff.
4912b65585SGordon Ross 	 * Further wcnt checks below.
5012b65585SGordon Ross 	 */
5112b65585SGordon Ross 	if (sr->smb_wct < 10) {
5212b65585SGordon Ross 		rc = -1;
5312b65585SGordon Ross 		goto done;
5412b65585SGordon Ross 	}
55da6c28aaSamw 
5612b65585SGordon Ross 	/*
5712b65585SGordon Ross 	 * Parse common part of SMB session setup.
5812b65585SGordon Ross 	 * skip: vcnumber(2), sesskey(4)
5912b65585SGordon Ross 	 */
6012b65585SGordon Ross 	rc = smbsr_decode_vwv(sr, "b.www6.",
6112b65585SGordon Ross 	    &sr->andx_com, &sr->andx_off,
6212b65585SGordon Ross 	    &sinfo->ssi_maxbufsize, &sinfo->ssi_maxmpxcount);
6312b65585SGordon Ross 	if (rc != 0)
6412b65585SGordon Ross 		goto done;
65da6c28aaSamw 
6612b65585SGordon Ross 	if (sr->session->dialect < NT_LM_0_12) {
67148c5f43SAlan Wright 
6812b65585SGordon Ross 		sinfo->ssi_type = SMB_SSNSETUP_PRE_NTLM012;
6912b65585SGordon Ross 		sinfo->ssi_capabilities = 0;
70148c5f43SAlan Wright 
7112b65585SGordon Ross 		rc = smbsr_decode_vwv(sr, "w4.",
7212b65585SGordon Ross 		    &sinfo->ssi_lmpwlen);
737b59d02dSjb 		if (rc != 0)
7412b65585SGordon Ross 			goto done;
75da6c28aaSamw 
7612b65585SGordon Ross 		sinfo->ssi_lmpwd = smb_srm_zalloc(sr, sinfo->ssi_lmpwlen + 1);
7712b65585SGordon Ross 		rc = smbsr_decode_data(sr, "%#c", sr, sinfo->ssi_lmpwlen,
7812b65585SGordon Ross 		    sinfo->ssi_lmpwd);
799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc != 0)
8012b65585SGordon Ross 			goto done;
81da6c28aaSamw 
8212b65585SGordon Ross 		sinfo->ssi_lmpwd[sinfo->ssi_lmpwlen] = 0;
83da6c28aaSamw 
84148c5f43SAlan Wright 		if (smbsr_decode_data(sr, "%u", sr, &sinfo->ssi_user) != 0)
85148c5f43SAlan Wright 			sinfo->ssi_user = "";
86da6c28aaSamw 
87148c5f43SAlan Wright 		if (smbsr_decode_data(sr, "%u", sr, &sinfo->ssi_domain) != 0)
88148c5f43SAlan Wright 			sinfo->ssi_domain = "";
89da6c28aaSamw 
9012b65585SGordon Ross 		goto part2;
9112b65585SGordon Ross 	}
9212b65585SGordon Ross 
9312b65585SGordon Ross 	/*
9412b65585SGordon Ross 	 * We have dialect >= NT_LM_0_12
9512b65585SGordon Ross 	 */
9612b65585SGordon Ross 	if (sr->smb_wct == 13) {
9712b65585SGordon Ross 		/* Old style (non-extended) request. */
9812b65585SGordon Ross 		sinfo->ssi_type = SMB_SSNSETUP_NTLM012_NOEXT;
9912b65585SGordon Ross 
10012b65585SGordon Ross 		rc = smbsr_decode_vwv(sr, "ww4.l",
10112b65585SGordon Ross 		    &sinfo->ssi_lmpwlen,
10212b65585SGordon Ross 		    &sinfo->ssi_ntpwlen,
10312b65585SGordon Ross 		    &sinfo->ssi_capabilities);
10412b65585SGordon Ross 		if (rc != 0)
10512b65585SGordon Ross 			goto done;
10612b65585SGordon Ross 
10712b65585SGordon Ross 		/* paranoid: ignore cap. ext. sec. here */
10812b65585SGordon Ross 		sinfo->ssi_capabilities &= ~CAP_EXTENDED_SECURITY;
10912b65585SGordon Ross 
11012b65585SGordon Ross 		sinfo->ssi_lmpwd = smb_srm_zalloc(sr, sinfo->ssi_lmpwlen + 1);
11112b65585SGordon Ross 		sinfo->ssi_ntpwd = smb_srm_zalloc(sr, sinfo->ssi_ntpwlen + 1);
11212b65585SGordon Ross 
11312b65585SGordon Ross 		rc = smbsr_decode_data(sr, "%#c#cuu", sr,
11412b65585SGordon Ross 		    sinfo->ssi_lmpwlen, sinfo->ssi_lmpwd,
11512b65585SGordon Ross 		    sinfo->ssi_ntpwlen, sinfo->ssi_ntpwd,
11612b65585SGordon Ross 		    &sinfo->ssi_user, &sinfo->ssi_domain);
11712b65585SGordon Ross 		if (rc != 0)
11812b65585SGordon Ross 			goto done;
11912b65585SGordon Ross 
12012b65585SGordon Ross 		sinfo->ssi_lmpwd[sinfo->ssi_lmpwlen] = 0;
12112b65585SGordon Ross 		sinfo->ssi_ntpwd[sinfo->ssi_ntpwlen] = 0;
12212b65585SGordon Ross 
12312b65585SGordon Ross 		goto part2;
12412b65585SGordon Ross 	}
12512b65585SGordon Ross 
12612b65585SGordon Ross 	if (sr->smb_wct == 12) {
12712b65585SGordon Ross 		/* New style (extended) request. */
12812b65585SGordon Ross 		sinfo->ssi_type = SMB_SSNSETUP_NTLM012_EXTSEC;
12912b65585SGordon Ross 
13012b65585SGordon Ross 		rc = smbsr_decode_vwv(sr, "w4.l",
13112b65585SGordon Ross 		    &sinfo->ssi_iseclen,
13212b65585SGordon Ross 		    &sinfo->ssi_capabilities);
13312b65585SGordon Ross 		if (rc != 0)
13412b65585SGordon Ross 			goto done;
13512b65585SGordon Ross 
13612b65585SGordon Ross 		if ((sinfo->ssi_capabilities & CAP_EXTENDED_SECURITY) == 0) {
13712b65585SGordon Ross 			rc = -1;
13812b65585SGordon Ross 			goto done;
13912b65585SGordon Ross 		}
14012b65585SGordon Ross 
14112b65585SGordon Ross 		sinfo->ssi_isecblob = smb_srm_zalloc(sr, sinfo->ssi_iseclen);
14212b65585SGordon Ross 		rc = smbsr_decode_data(sr, "%#c", sr,
14312b65585SGordon Ross 		    sinfo->ssi_iseclen, sinfo->ssi_isecblob);
14412b65585SGordon Ross 		if (rc != 0)
14512b65585SGordon Ross 			goto done;
14612b65585SGordon Ross 
14712b65585SGordon Ross 		goto part2;
148da6c28aaSamw 	}
149da6c28aaSamw 
15012b65585SGordon Ross 	/* Invalid message */
15112b65585SGordon Ross 	rc = -1;
15212b65585SGordon Ross 	goto done;
15312b65585SGordon Ross 
15412b65585SGordon Ross part2:
15512b65585SGordon Ross 	/*
15612b65585SGordon Ross 	 * Get the "Native OS" and "Native LanMan" strings.
15712b65585SGordon Ross 	 * These are not critical to protocol function, so
15812b65585SGordon Ross 	 * if we can't parse them, just guess "NT".
15912b65585SGordon Ross 	 * These strings are free'd with the sr.
16012b65585SGordon Ross 	 *
16112b65585SGordon Ross 	 * In NTLM 0.12, the padding between the Native OS and Native LM
16212b65585SGordon Ross 	 * is a bit strange.  On NT4.0, there is a 2 byte pad between the
16312b65585SGordon Ross 	 * OS (Windows NT 1381) and LM (Windows NT 4.0).  On Windows 2000,
16412b65585SGordon Ross 	 * there is no padding between the OS (Windows 2000 2195) and LM
16512b65585SGordon Ross 	 * (Windows 2000 5.0). If the padding is removed from the decode
16612b65585SGordon Ross 	 * string the NT4.0 LM comes out as an empty string.  So if the
16712b65585SGordon Ross 	 * client's native OS is Win NT, assume extra padding.
16812b65585SGordon Ross 	 */
16912b65585SGordon Ross 	rc = smbsr_decode_data(sr, "%u", sr, &native_os);
17012b65585SGordon Ross 	if (rc != 0 || native_os == NULL)
17112b65585SGordon Ross 		sinfo->ssi_native_os = NATIVE_OS_WINNT;
17212b65585SGordon Ross 	else
17312b65585SGordon Ross 		sinfo->ssi_native_os = smbnative_os_value(native_os);
17412b65585SGordon Ross 
17512b65585SGordon Ross 	if (sinfo->ssi_native_os == NATIVE_OS_WINNT)
17612b65585SGordon Ross 		rc = smbsr_decode_data(sr, "%,u", sr, &native_lm);
17712b65585SGordon Ross 	else
17812b65585SGordon Ross 		rc = smbsr_decode_data(sr, "%u", sr, &native_lm);
17912b65585SGordon Ross 	if (rc != 0 || native_lm == NULL)
18012b65585SGordon Ross 		sinfo->ssi_native_lm = NATIVE_LM_NT;
18112b65585SGordon Ross 	else
18212b65585SGordon Ross 		sinfo->ssi_native_lm = smbnative_lm_value(native_lm);
18312b65585SGordon Ross 	rc = 0;
18412b65585SGordon Ross 
18512b65585SGordon Ross done:
18612b65585SGordon Ross 	if (rc != 0) {
18712b65585SGordon Ross 		cmn_err(CE_NOTE,
18812b65585SGordon Ross 		    "SmbSessonSetupX: client %s invalid request",
18912b65585SGordon Ross 		    sr->session->ip_addr_str);
19012b65585SGordon Ross 	}
191148c5f43SAlan Wright 
19293bc28dbSGordon Ross 	DTRACE_SMB_START(op__SessionSetupX, smb_request_t *, sr);
193148c5f43SAlan Wright 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
194148c5f43SAlan Wright }
195148c5f43SAlan Wright 
196148c5f43SAlan Wright void
smb_post_session_setup_andx(smb_request_t * sr)197148c5f43SAlan Wright smb_post_session_setup_andx(smb_request_t *sr)
198148c5f43SAlan Wright {
199148c5f43SAlan Wright 	smb_arg_sessionsetup_t	*sinfo = sr->sr_ssetup;
200148c5f43SAlan Wright 
20193bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__SessionSetupX, smb_request_t *, sr);
202148c5f43SAlan Wright 
20312b65585SGordon Ross 	if (sinfo->ssi_lmpwd != NULL)
20412b65585SGordon Ross 		bzero(sinfo->ssi_lmpwd, sinfo->ssi_lmpwlen);
205148c5f43SAlan Wright 
20612b65585SGordon Ross 	if (sinfo->ssi_ntpwd != NULL)
20712b65585SGordon Ross 		bzero(sinfo->ssi_ntpwd, sinfo->ssi_ntpwlen);
208148c5f43SAlan Wright }
209148c5f43SAlan Wright 
210148c5f43SAlan Wright /*
211148c5f43SAlan Wright  *
212148c5f43SAlan Wright  * NT systems use different native OS and native LanMan values dependent on
213148c5f43SAlan Wright  * whether they are acting as a client or a server.  NT 4.0 server responds
214148c5f43SAlan Wright  * with the following values:
215148c5f43SAlan Wright  *
216148c5f43SAlan Wright  *      NativeOS:       Windows NT 4.0
217148c5f43SAlan Wright  *      NativeLM:       NT LAN Manager 4.0
218148c5f43SAlan Wright  */
219148c5f43SAlan Wright smb_sdrc_t
smb_com_session_setup_andx(smb_request_t * sr)220148c5f43SAlan Wright smb_com_session_setup_andx(smb_request_t *sr)
221148c5f43SAlan Wright {
222148c5f43SAlan Wright 	smb_arg_sessionsetup_t	*sinfo = sr->sr_ssetup;
22312b65585SGordon Ross 	uint32_t		status;
22412b65585SGordon Ross 	uint16_t		action;
225148c5f43SAlan Wright 	int			rc;
226148c5f43SAlan Wright 
2277f667e74Sjose borrego 	/*
22812b65585SGordon Ross 	 * Some stuff we do only in the first in a (possible)
22912b65585SGordon Ross 	 * sequence of session setup requests.
2307f667e74Sjose borrego 	 */
23112b65585SGordon Ross 	if (sinfo->ssi_type != SMB_SSNSETUP_NTLM012_EXTSEC ||
23212b65585SGordon Ross 	    sr->smb_uid == 0 || sr->smb_uid == 0xFFFF) {
2337f667e74Sjose borrego 
23412b65585SGordon Ross 		/* This is a first (or only) call */
23512b65585SGordon Ross 		sr->session->smb_msg_size = sinfo->ssi_maxbufsize;
23612b65585SGordon Ross 		sr->session->smb_max_mpx = sinfo->ssi_maxmpxcount;
23712b65585SGordon Ross 		sr->session->capabilities = sinfo->ssi_capabilities;
23812b65585SGordon Ross 		sr->session->native_os = sinfo->ssi_native_os;
23912b65585SGordon Ross 		sr->session->native_lm = sinfo->ssi_native_lm;
2407f667e74Sjose borrego 	}
2417f667e74Sjose borrego 
242*1160dcf7SMatt Barden 	/* RejectUnencryptedAccess precludes SMB1 access */
243*1160dcf7SMatt Barden 	if (sr->sr_server->sv_cfg.skc_encrypt == SMB_CONFIG_REQUIRED) {
244*1160dcf7SMatt Barden 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
245*1160dcf7SMatt Barden 		    ERRDOS, ERROR_ACCESS_DENIED);
246*1160dcf7SMatt Barden 		return (SDRC_ERROR);
247*1160dcf7SMatt Barden 	}
248*1160dcf7SMatt Barden 
249b819cea2SGordon Ross 	/*
25012b65585SGordon Ross 	 * The "meat" of authentication happens here.
251b819cea2SGordon Ross 	 */
25212b65585SGordon Ross 	if (sinfo->ssi_type == SMB_SSNSETUP_NTLM012_EXTSEC)
25312b65585SGordon Ross 		status = smb_authenticate_ext(sr);
25412b65585SGordon Ross 	else
25512b65585SGordon Ross 		status = smb_authenticate_old(sr);
256148c5f43SAlan Wright 
25712b65585SGordon Ross 	switch (status) {
258148c5f43SAlan Wright 
25912b65585SGordon Ross 	case NT_STATUS_SUCCESS:
26012b65585SGordon Ross 		break;
261148c5f43SAlan Wright 
262961125f2SGordon Ross 	/*
26312b65585SGordon Ross 	 * This is not really an error, but tells the client
26412b65585SGordon Ross 	 * it should send another session setup request.
265961125f2SGordon Ross 	 */
26612b65585SGordon Ross 	case NT_STATUS_MORE_PROCESSING_REQUIRED:
26712b65585SGordon Ross 		smbsr_error(sr, status, 0, 0);
26812b65585SGordon Ross 		break;
269148c5f43SAlan Wright 
27012b65585SGordon Ross 	case NT_STATUS_ACCESS_DENIED:
27112b65585SGordon Ross 		smbsr_error(sr, status, ERRDOS, ERROR_ACCESS_DENIED);
27212b65585SGordon Ross 		return (SDRC_ERROR);
273148c5f43SAlan Wright 
27412b65585SGordon Ross 	case NT_STATUS_TOO_MANY_SESSIONS:
27512b65585SGordon Ross 		smbsr_error(sr, status, ERRSRV, ERRtoomanyuids);
27612b65585SGordon Ross 		return (SDRC_ERROR);
277148c5f43SAlan Wright 
27812b65585SGordon Ross 	case NT_STATUS_NO_LOGON_SERVERS:
27912b65585SGordon Ross 		smbsr_error(sr, status, ERRDOS, ERROR_NO_LOGON_SERVERS);
28012b65585SGordon Ross 		return (SDRC_ERROR);
281148c5f43SAlan Wright 
28212b65585SGordon Ross 	case NT_STATUS_NETLOGON_NOT_STARTED:
28312b65585SGordon Ross 		smbsr_error(sr, status, ERRDOS, ERROR_NETLOGON_NOT_STARTED);
28412b65585SGordon Ross 		return (SDRC_ERROR);
285148c5f43SAlan Wright 
28612b65585SGordon Ross 	case NT_STATUS_USER_SESSION_DELETED:
28712b65585SGordon Ross 		smbsr_error(sr, status, ERRSRV, ERRbaduid);
28812b65585SGordon Ross 		return (SDRC_ERROR);
289148c5f43SAlan Wright 
29012b65585SGordon Ross 	case NT_STATUS_INSUFF_SERVER_RESOURCES:
29112b65585SGordon Ross 		smbsr_error(sr, status, ERRSRV, ERRnoresource);
29212b65585SGordon Ross 		return (SDRC_ERROR);
293148c5f43SAlan Wright 
29412b65585SGordon Ross 	case NT_STATUS_INTERNAL_ERROR:
29512b65585SGordon Ross 	default:
29612b65585SGordon Ross 		smbsr_error(sr, status, ERRSRV, ERRsrverror);
29712b65585SGordon Ross 		return (SDRC_ERROR);
29812b65585SGordon Ross 	}
299148c5f43SAlan Wright 
30012b65585SGordon Ross 	action = SMB_USER_IS_GUEST(sr->uid_user) ? 1 : 0;
301148c5f43SAlan Wright 
30212b65585SGordon Ross 	switch (sinfo->ssi_type) {
303148c5f43SAlan Wright 
30412b65585SGordon Ross 	default:
30512b65585SGordon Ross 	case SMB_SSNSETUP_PRE_NTLM012:
30612b65585SGordon Ross 	case SMB_SSNSETUP_NTLM012_NOEXT:
307148c5f43SAlan Wright 
30812b65585SGordon Ross 		rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu",
30912b65585SGordon Ross 		    3,
31012b65585SGordon Ross 		    sr->andx_com,
31112b65585SGordon Ross 		    -1,			/* andx_off */
31212b65585SGordon Ross 		    action,
31312b65585SGordon Ross 		    VAR_BCC,
31412b65585SGordon Ross 		    sr,
31512b65585SGordon Ross 		    sr->sr_cfg->skc_native_os,
31612b65585SGordon Ross 		    sr->sr_cfg->skc_native_lm,
31712b65585SGordon Ross 		    sr->sr_cfg->skc_nbdomain);
31812b65585SGordon Ross 		break;
31912b65585SGordon Ross 
32012b65585SGordon Ross 	case SMB_SSNSETUP_NTLM012_EXTSEC:
32112b65585SGordon Ross 
32212b65585SGordon Ross 		rc = smbsr_encode_result(sr, 4, VAR_BCC, "bb.wwww%#cuuu",
32312b65585SGordon Ross 		    4,
32412b65585SGordon Ross 		    sr->andx_com,
32512b65585SGordon Ross 		    -1,			/* andx_off */
32612b65585SGordon Ross 		    action,
32712b65585SGordon Ross 		    sinfo->ssi_oseclen,
32812b65585SGordon Ross 		    VAR_BCC,
32912b65585SGordon Ross 		    sr,
33012b65585SGordon Ross 		    sinfo->ssi_oseclen,
33112b65585SGordon Ross 		    sinfo->ssi_osecblob,
33212b65585SGordon Ross 		    sr->sr_cfg->skc_native_os,
33312b65585SGordon Ross 		    sr->sr_cfg->skc_native_lm,
33412b65585SGordon Ross 		    sr->sr_cfg->skc_nbdomain);
33512b65585SGordon Ross 		break;
33612b65585SGordon Ross 	}
3377f667e74Sjose borrego 
33812b65585SGordon Ross 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
3397f667e74Sjose borrego }
340