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