15331Samw /*
25331Samw * CDDL HEADER START
35331Samw *
45331Samw * The contents of this file are subject to the terms of the
55331Samw * Common Development and Distribution License (the "License").
65331Samw * You may not use this file except in compliance with the License.
75331Samw *
85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw * or http://www.opensolaris.org/os/licensing.
105331Samw * See the License for the specific language governing permissions
115331Samw * and limitations under the License.
125331Samw *
135331Samw * When distributing Covered Code, include this CDDL HEADER in each
145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw * If applicable, add the following below this CDDL HEADER, with the
165331Samw * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw *
195331Samw * CDDL HEADER END
205331Samw */
215331Samw /*
2212508Samw@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
235331Samw */
245331Samw
255331Samw #include <sys/types.h>
2612508Samw@Sun.COM #include <sys/sid.h>
2712508Samw@Sun.COM #include <sys/priv_names.h>
285331Samw #include <sys/socket.h>
295331Samw #include <netinet/in.h>
3012508Samw@Sun.COM #include <smbsrv/smb_idmap.h>
3110966SJordan.Brown@Sun.COM #include <smbsrv/smb_kproto.h>
325331Samw #include <smbsrv/smb_token.h>
335331Samw
3412508Samw@Sun.COM static int smb_authenticate(smb_request_t *, smb_arg_sessionsetup_t *,
3512508Samw@Sun.COM smb_session_key_t **);
36*12890SJoyce.McIntosh@Sun.COM static int smb_authenticate_core(smb_request_t *, smb_arg_sessionsetup_t *,
37*12890SJoyce.McIntosh@Sun.COM smb_session_key_t **);
3812508Samw@Sun.COM static cred_t *smb_cred_create(smb_token_t *);
3912508Samw@Sun.COM static void smb_cred_set_sid(smb_id_t *id, ksid_t *ksid);
4012508Samw@Sun.COM static ksidlist_t *smb_cred_set_sidlist(smb_ids_t *token_grps);
4112508Samw@Sun.COM static uint32_t smb_priv_xlate(smb_token_t *);
428670SJose.Borrego@Sun.COM
4312508Samw@Sun.COM /*
4412508Samw@Sun.COM * In NTLM 0.12, the padding between the Native OS and Native LM is a bit
4512508Samw@Sun.COM * strange. On NT4.0, there is a 2 byte pad between the OS (Windows NT 1381)
4612508Samw@Sun.COM * and LM (Windows NT 4.0). On Windows 2000, there is no padding between
4712508Samw@Sun.COM * the OS (Windows 2000 2195) and LM (Windows 2000 5.0).
4812508Samw@Sun.COM * If the padding is removed from the decode string the NT4.0 LM comes out
4912508Samw@Sun.COM * as an empty string. So if the client's native OS is Win NT we consider
5012508Samw@Sun.COM * the padding otherwise we don't.
5112508Samw@Sun.COM *
5212508Samw@Sun.COM * For Pre-NTLM 0.12, despite the CIFS/1.0 spec, the user and domain are
5312508Samw@Sun.COM * not always present in the message. We try to get the account name and
5412508Samw@Sun.COM * the primary domain but we don't care about the the native OS or native
5512508Samw@Sun.COM * LM fields.
5612508Samw@Sun.COM *
5712508Samw@Sun.COM * If the Native LM cannot be determined, default to Windows NT.
5812508Samw@Sun.COM */
596030Sjb150015 smb_sdrc_t
smb_pre_session_setup_andx(smb_request_t * sr)606139Sjb150015 smb_pre_session_setup_andx(smb_request_t *sr)
616139Sjb150015 {
6212508Samw@Sun.COM smb_arg_sessionsetup_t *sinfo;
6312508Samw@Sun.COM char *native_os;
6412508Samw@Sun.COM char *native_lm;
6512508Samw@Sun.COM uint16_t maxbufsize;
6612508Samw@Sun.COM uint16_t vcnumber;
6712508Samw@Sun.COM int rc = 0;
6812508Samw@Sun.COM
6912508Samw@Sun.COM sinfo = smb_srm_zalloc(sr, sizeof (smb_arg_sessionsetup_t));
7012508Samw@Sun.COM sr->sr_ssetup = sinfo;
7112508Samw@Sun.COM
7212508Samw@Sun.COM if (sr->session->dialect >= NT_LM_0_12) {
7312508Samw@Sun.COM rc = smbsr_decode_vwv(sr, "b.wwwwlww4.l", &sr->andx_com,
7412508Samw@Sun.COM &sr->andx_off, &maxbufsize,
7512508Samw@Sun.COM &sinfo->ssi_maxmpxcount, &vcnumber,
7612508Samw@Sun.COM &sinfo->ssi_sesskey, &sinfo->ssi_cipwlen,
7712508Samw@Sun.COM &sinfo->ssi_cspwlen, &sinfo->ssi_capabilities);
7812508Samw@Sun.COM if (rc != 0)
7912508Samw@Sun.COM goto pre_session_setup_andx_done;
8012508Samw@Sun.COM
8112508Samw@Sun.COM sinfo->ssi_cipwd = smb_srm_zalloc(sr, sinfo->ssi_cipwlen + 1);
8212508Samw@Sun.COM sinfo->ssi_cspwd = smb_srm_zalloc(sr, sinfo->ssi_cspwlen + 1);
8312508Samw@Sun.COM
8412508Samw@Sun.COM rc = smbsr_decode_data(sr, "%#c#cuuu",
8512508Samw@Sun.COM sr,
8612508Samw@Sun.COM sinfo->ssi_cipwlen, sinfo->ssi_cipwd,
8712508Samw@Sun.COM sinfo->ssi_cspwlen, sinfo->ssi_cspwd,
8812508Samw@Sun.COM &sinfo->ssi_user,
8912508Samw@Sun.COM &sinfo->ssi_domain,
9012508Samw@Sun.COM &native_os);
9112508Samw@Sun.COM if (rc != 0)
9212508Samw@Sun.COM goto pre_session_setup_andx_done;
9312508Samw@Sun.COM
9412508Samw@Sun.COM sinfo->ssi_cipwd[sinfo->ssi_cipwlen] = 0;
9512508Samw@Sun.COM sinfo->ssi_cspwd[sinfo->ssi_cspwlen] = 0;
9612508Samw@Sun.COM
9712508Samw@Sun.COM sr->session->native_os = smbnative_os_value(native_os);
9812508Samw@Sun.COM
9912508Samw@Sun.COM if (sr->session->native_os == NATIVE_OS_WINNT)
10012508Samw@Sun.COM rc = smbsr_decode_data(sr, "%,u", sr, &native_lm);
10112508Samw@Sun.COM else
10212508Samw@Sun.COM rc = smbsr_decode_data(sr, "%u", sr, &native_lm);
10312508Samw@Sun.COM
10412508Samw@Sun.COM if (rc != 0 || native_lm == NULL)
10512508Samw@Sun.COM native_lm = "NT LAN Manager 4.0";
10612508Samw@Sun.COM
10712508Samw@Sun.COM sr->session->native_lm = smbnative_lm_value(native_lm);
10812508Samw@Sun.COM } else {
10912508Samw@Sun.COM rc = smbsr_decode_vwv(sr, "b.wwwwlw4.", &sr->andx_com,
11012508Samw@Sun.COM &sr->andx_off, &maxbufsize,
11112508Samw@Sun.COM &sinfo->ssi_maxmpxcount, &vcnumber,
11212508Samw@Sun.COM &sinfo->ssi_sesskey, &sinfo->ssi_cipwlen);
11312508Samw@Sun.COM if (rc != 0)
11412508Samw@Sun.COM goto pre_session_setup_andx_done;
11512508Samw@Sun.COM
11612508Samw@Sun.COM sinfo->ssi_cipwd = smb_srm_zalloc(sr, sinfo->ssi_cipwlen + 1);
11712508Samw@Sun.COM rc = smbsr_decode_data(sr, "%#c", sr, sinfo->ssi_cipwlen,
11812508Samw@Sun.COM sinfo->ssi_cipwd);
11912508Samw@Sun.COM if (rc != 0)
12012508Samw@Sun.COM goto pre_session_setup_andx_done;
12112508Samw@Sun.COM
12212508Samw@Sun.COM sinfo->ssi_cipwd[sinfo->ssi_cipwlen] = 0;
12312508Samw@Sun.COM
12412508Samw@Sun.COM if (smbsr_decode_data(sr, "%u", sr, &sinfo->ssi_user) != 0)
12512508Samw@Sun.COM sinfo->ssi_user = "";
12612508Samw@Sun.COM
12712508Samw@Sun.COM if (smbsr_decode_data(sr, "%u", sr, &sinfo->ssi_domain) != 0)
12812508Samw@Sun.COM sinfo->ssi_domain = "";
12912508Samw@Sun.COM
13012508Samw@Sun.COM native_lm = "NT LAN Manager 4.0";
13112508Samw@Sun.COM sr->session->native_os = NATIVE_OS_WINNT;
13212508Samw@Sun.COM sr->session->native_lm = smbnative_lm_value(native_lm);
13312508Samw@Sun.COM }
13412508Samw@Sun.COM
13512508Samw@Sun.COM sr->session->vcnumber = vcnumber;
13612508Samw@Sun.COM sr->session->smb_msg_size = maxbufsize;
13712508Samw@Sun.COM
13812508Samw@Sun.COM pre_session_setup_andx_done:
13912508Samw@Sun.COM DTRACE_SMB_2(op__SessionSetupX__start, smb_request_t *, sr,
14012508Samw@Sun.COM smb_arg_sessionsetup_t, sinfo);
14112508Samw@Sun.COM return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
1426139Sjb150015 }
1436139Sjb150015
1446139Sjb150015 void
smb_post_session_setup_andx(smb_request_t * sr)1456139Sjb150015 smb_post_session_setup_andx(smb_request_t *sr)
1466139Sjb150015 {
14712508Samw@Sun.COM smb_arg_sessionsetup_t *sinfo = sr->sr_ssetup;
14812508Samw@Sun.COM
14912508Samw@Sun.COM DTRACE_SMB_2(op__SessionSetupX__done, smb_request_t *, sr,
15012508Samw@Sun.COM smb_arg_sessionsetup_t, sinfo);
15112508Samw@Sun.COM
15212508Samw@Sun.COM if (sinfo->ssi_cipwd != NULL)
15312508Samw@Sun.COM bzero(sinfo->ssi_cipwd, sinfo->ssi_cipwlen + 1);
15412508Samw@Sun.COM
15512508Samw@Sun.COM if (sinfo->ssi_cspwd != NULL)
15612508Samw@Sun.COM bzero(sinfo->ssi_cspwd, sinfo->ssi_cspwlen + 1);
1576139Sjb150015 }
1586139Sjb150015
15912508Samw@Sun.COM /*
16012508Samw@Sun.COM * If the vcnumber is zero, discard any other connections associated with
16112508Samw@Sun.COM * this client.
16212508Samw@Sun.COM *
16312508Samw@Sun.COM * If signing has not already been enabled on this session check to see if
16412508Samw@Sun.COM * it should be enabled. The first authenticated logon provides the MAC
16512508Samw@Sun.COM * key and sequence numbers for signing all subsequent sessions on the same
16612508Samw@Sun.COM * connection.
16712508Samw@Sun.COM *
16812508Samw@Sun.COM * NT systems use different native OS and native LanMan values dependent on
16912508Samw@Sun.COM * whether they are acting as a client or a server. NT 4.0 server responds
17012508Samw@Sun.COM * with the following values:
17112508Samw@Sun.COM *
17212508Samw@Sun.COM * NativeOS: Windows NT 4.0
17312508Samw@Sun.COM * NativeLM: NT LAN Manager 4.0
17412508Samw@Sun.COM */
1756139Sjb150015 smb_sdrc_t
smb_com_session_setup_andx(smb_request_t * sr)1766139Sjb150015 smb_com_session_setup_andx(smb_request_t *sr)
1775331Samw {
17812508Samw@Sun.COM smb_arg_sessionsetup_t *sinfo = sr->sr_ssetup;
17911963SAfshin.Ardakani@Sun.COM smb_session_key_t *session_key = NULL;
18011963SAfshin.Ardakani@Sun.COM char ipaddr_buf[INET6_ADDRSTRLEN];
18111963SAfshin.Ardakani@Sun.COM int rc;
1825331Samw
18312508Samw@Sun.COM if (sr->session->vcnumber == 0)
1846139Sjb150015 smb_server_reconnection_check(sr->sr_server, sr->session);
1855331Samw
18612508Samw@Sun.COM if (smb_authenticate(sr, sinfo, &session_key) != 0)
1878670SJose.Borrego@Sun.COM return (SDRC_ERROR);
1888670SJose.Borrego@Sun.COM
18912508Samw@Sun.COM if (sr->session->native_lm == NATIVE_LM_WIN2000)
19012508Samw@Sun.COM sinfo->ssi_capabilities |= CAP_LARGE_FILES |
1919021Samw@Sun.COM CAP_LARGE_READX | CAP_LARGE_WRITEX;
1929832Samw@Sun.COM
193*12890SJoyce.McIntosh@Sun.COM if (!smb_oplock_levelII)
194*12890SJoyce.McIntosh@Sun.COM sr->session->capabilities &= ~CAP_LEVEL_II_OPLOCKS;
195*12890SJoyce.McIntosh@Sun.COM
19612508Samw@Sun.COM sr->session->capabilities = sinfo->ssi_capabilities;
1975331Samw
1985331Samw if (!(sr->session->signing.flags & SMB_SIGNING_ENABLED) &&
1995331Samw (sr->session->secmode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) &&
2005331Samw (sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) &&
2015331Samw session_key)
20212508Samw@Sun.COM smb_sign_init(sr, session_key, (char *)sinfo->ssi_cspwd,
20312508Samw@Sun.COM sinfo->ssi_cspwlen);
2045331Samw
2057348SJose.Borrego@Sun.COM if (!(sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) &&
2067348SJose.Borrego@Sun.COM (sr->sr_cfg->skc_signing_required)) {
2078670SJose.Borrego@Sun.COM (void) smb_inet_ntop(&sr->session->ipaddr, ipaddr_buf,
2088670SJose.Borrego@Sun.COM SMB_IPSTRLEN(sr->session->ipaddr.a_family));
2097348SJose.Borrego@Sun.COM cmn_err(CE_NOTE,
21012508Samw@Sun.COM "SmbSessonSetupX: client %s does not support signing",
2117348SJose.Borrego@Sun.COM ipaddr_buf);
2127348SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_LOGON_FAILURE,
2137348SJose.Borrego@Sun.COM ERRDOS, ERROR_LOGON_FAILURE);
2147348SJose.Borrego@Sun.COM return (SDRC_ERROR);
2157348SJose.Borrego@Sun.COM }
2167348SJose.Borrego@Sun.COM
2176030Sjb150015 rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu",
2185331Samw 3,
2195331Samw sr->andx_com,
2205331Samw -1, /* andx_off */
22112508Samw@Sun.COM sinfo->ssi_guest ? 1 : 0,
2225331Samw VAR_BCC,
2235331Samw sr,
22411963SAfshin.Ardakani@Sun.COM smbnative_os_str(&sr->sr_cfg->skc_version),
22511963SAfshin.Ardakani@Sun.COM smbnative_lm_str(&sr->sr_cfg->skc_version),
2268670SJose.Borrego@Sun.COM sr->sr_cfg->skc_nbdomain);
2275331Samw
2286139Sjb150015 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
2295331Samw }
2308670SJose.Borrego@Sun.COM
231*12890SJoyce.McIntosh@Sun.COM static int
smb_authenticate(smb_request_t * sr,smb_arg_sessionsetup_t * sinfo,smb_session_key_t ** session_key)232*12890SJoyce.McIntosh@Sun.COM smb_authenticate(smb_request_t *sr, smb_arg_sessionsetup_t *sinfo,
233*12890SJoyce.McIntosh@Sun.COM smb_session_key_t **session_key)
234*12890SJoyce.McIntosh@Sun.COM {
235*12890SJoyce.McIntosh@Sun.COM int rc;
236*12890SJoyce.McIntosh@Sun.COM smb_server_t *sv = sr->sr_server;
237*12890SJoyce.McIntosh@Sun.COM
238*12890SJoyce.McIntosh@Sun.COM if (smb_threshold_enter(&sv->sv_ssetup_ct) != 0) {
239*12890SJoyce.McIntosh@Sun.COM smbsr_error(sr, RPC_NT_SERVER_TOO_BUSY, 0, 0);
240*12890SJoyce.McIntosh@Sun.COM return (-1);
241*12890SJoyce.McIntosh@Sun.COM }
242*12890SJoyce.McIntosh@Sun.COM
243*12890SJoyce.McIntosh@Sun.COM rc = smb_authenticate_core(sr, sinfo, session_key);
244*12890SJoyce.McIntosh@Sun.COM smb_threshold_exit(&sv->sv_ssetup_ct, sv);
245*12890SJoyce.McIntosh@Sun.COM return (rc);
246*12890SJoyce.McIntosh@Sun.COM }
247*12890SJoyce.McIntosh@Sun.COM
2488670SJose.Borrego@Sun.COM /*
24912508Samw@Sun.COM * Authenticate a user. If the user has already been authenticated on
25012508Samw@Sun.COM * this session, we can simply dup the user and return.
2518670SJose.Borrego@Sun.COM *
25212508Samw@Sun.COM * Otherwise, the user information is passed to smbd for authentication.
25312508Samw@Sun.COM * If smbd can authenticate the user an access token is returned and we
25412508Samw@Sun.COM * generate a cred and new user based on the token.
2558670SJose.Borrego@Sun.COM */
2568670SJose.Borrego@Sun.COM static int
smb_authenticate_core(smb_request_t * sr,smb_arg_sessionsetup_t * sinfo,smb_session_key_t ** session_key)257*12890SJoyce.McIntosh@Sun.COM smb_authenticate_core(smb_request_t *sr, smb_arg_sessionsetup_t *sinfo,
2588670SJose.Borrego@Sun.COM smb_session_key_t **session_key)
2598670SJose.Borrego@Sun.COM {
26011963SAfshin.Ardakani@Sun.COM char *hostname = sr->sr_cfg->skc_hostname;
26111963SAfshin.Ardakani@Sun.COM int security = sr->sr_cfg->skc_secmode;
26212508Samw@Sun.COM smb_token_t *token = NULL;
26311963SAfshin.Ardakani@Sun.COM smb_user_t *user = NULL;
26411963SAfshin.Ardakani@Sun.COM smb_logon_t user_info;
26511963SAfshin.Ardakani@Sun.COM boolean_t need_lookup = B_FALSE;
26611963SAfshin.Ardakani@Sun.COM uint32_t privileges;
26711963SAfshin.Ardakani@Sun.COM cred_t *cr;
26811963SAfshin.Ardakani@Sun.COM char *buf = NULL;
26911963SAfshin.Ardakani@Sun.COM char *p;
2708670SJose.Borrego@Sun.COM
27111963SAfshin.Ardakani@Sun.COM bzero(&user_info, sizeof (smb_logon_t));
27212508Samw@Sun.COM user_info.lg_e_domain = sinfo->ssi_domain;
2738670SJose.Borrego@Sun.COM
27411963SAfshin.Ardakani@Sun.COM if ((*sinfo->ssi_user == '\0') &&
27511963SAfshin.Ardakani@Sun.COM (sinfo->ssi_cspwlen == 0) &&
2769832Samw@Sun.COM (sinfo->ssi_cipwlen == 0 ||
27711963SAfshin.Ardakani@Sun.COM (sinfo->ssi_cipwlen == 1 && *sinfo->ssi_cipwd == '\0'))) {
27811963SAfshin.Ardakani@Sun.COM user_info.lg_e_username = "anonymous";
27911963SAfshin.Ardakani@Sun.COM user_info.lg_flags |= SMB_ATF_ANON;
2809832Samw@Sun.COM } else {
28111963SAfshin.Ardakani@Sun.COM user_info.lg_e_username = sinfo->ssi_user;
2829832Samw@Sun.COM }
2839832Samw@Sun.COM
2848670SJose.Borrego@Sun.COM /*
28512508Samw@Sun.COM * Handle user@domain format. We need to retain the original
28612508Samw@Sun.COM * data as this is important in some forms of authentication.
2878670SJose.Borrego@Sun.COM */
2888670SJose.Borrego@Sun.COM if (*sinfo->ssi_domain == '\0') {
28912508Samw@Sun.COM buf = smb_srm_strdup(sr, sinfo->ssi_user);
2908670SJose.Borrego@Sun.COM if ((p = strchr(buf, '@')) != NULL) {
2918670SJose.Borrego@Sun.COM *p = '\0';
29211963SAfshin.Ardakani@Sun.COM user_info.lg_e_username = buf;
29311963SAfshin.Ardakani@Sun.COM user_info.lg_e_domain = p + 1;
2948670SJose.Borrego@Sun.COM }
2958670SJose.Borrego@Sun.COM }
2968670SJose.Borrego@Sun.COM
2978670SJose.Borrego@Sun.COM /*
29812508Samw@Sun.COM * If no domain name has been provided in domain mode we cannot
29912508Samw@Sun.COM * determine if this is a local user or a domain user without
30012508Samw@Sun.COM * obtaining an access token. So we postpone the lookup until
30112508Samw@Sun.COM * after authentication.
3028670SJose.Borrego@Sun.COM */
3038670SJose.Borrego@Sun.COM if (security == SMB_SECMODE_WORKGRP) {
3048670SJose.Borrego@Sun.COM user = smb_session_dup_user(sr->session, hostname,
30511963SAfshin.Ardakani@Sun.COM user_info.lg_e_username);
30611963SAfshin.Ardakani@Sun.COM } else if (*user_info.lg_e_domain != '\0') {
30711963SAfshin.Ardakani@Sun.COM user = smb_session_dup_user(sr->session, user_info.lg_e_domain,
30811963SAfshin.Ardakani@Sun.COM user_info.lg_e_username);
3098670SJose.Borrego@Sun.COM } else {
3108670SJose.Borrego@Sun.COM need_lookup = B_TRUE;
3118670SJose.Borrego@Sun.COM }
3128670SJose.Borrego@Sun.COM
3138670SJose.Borrego@Sun.COM if (user != NULL) {
31412508Samw@Sun.COM sinfo->ssi_guest = SMB_USER_IS_GUEST(user);
3158670SJose.Borrego@Sun.COM sr->user_cr = user->u_cred;
3168670SJose.Borrego@Sun.COM sr->smb_uid = user->u_uid;
3178670SJose.Borrego@Sun.COM sr->uid_user = user;
31812508Samw@Sun.COM return (0);
3198670SJose.Borrego@Sun.COM }
3208670SJose.Borrego@Sun.COM
32111963SAfshin.Ardakani@Sun.COM user_info.lg_level = NETR_NETWORK_LOGON;
32211963SAfshin.Ardakani@Sun.COM user_info.lg_domain = sinfo->ssi_domain;
32311963SAfshin.Ardakani@Sun.COM user_info.lg_username = sinfo->ssi_user;
32411963SAfshin.Ardakani@Sun.COM user_info.lg_workstation = sr->session->workstation;
32511963SAfshin.Ardakani@Sun.COM user_info.lg_clnt_ipaddr = sr->session->ipaddr;
32611963SAfshin.Ardakani@Sun.COM user_info.lg_local_ipaddr = sr->session->local_ipaddr;
32711963SAfshin.Ardakani@Sun.COM user_info.lg_local_port = sr->session->s_local_port;
32811963SAfshin.Ardakani@Sun.COM user_info.lg_challenge_key.val = sr->session->challenge_key;
32911963SAfshin.Ardakani@Sun.COM user_info.lg_challenge_key.len = sr->session->challenge_len;
33011963SAfshin.Ardakani@Sun.COM user_info.lg_nt_password.val = sinfo->ssi_cspwd;
33111963SAfshin.Ardakani@Sun.COM user_info.lg_nt_password.len = sinfo->ssi_cspwlen;
33211963SAfshin.Ardakani@Sun.COM user_info.lg_lm_password.val = sinfo->ssi_cipwd;
33311963SAfshin.Ardakani@Sun.COM user_info.lg_lm_password.len = sinfo->ssi_cipwlen;
33411963SAfshin.Ardakani@Sun.COM user_info.lg_native_os = sr->session->native_os;
33512508Samw@Sun.COM user_info.lg_native_lm = sr->session->native_lm;
3368670SJose.Borrego@Sun.COM
33712508Samw@Sun.COM DTRACE_PROBE1(smb__sessionsetup__clntinfo, smb_logon_t *, &user_info);
3388670SJose.Borrego@Sun.COM
33912508Samw@Sun.COM if ((token = smb_get_token(&user_info)) == NULL) {
3408670SJose.Borrego@Sun.COM smbsr_error(sr, 0, ERRSRV, ERRbadpw);
34112508Samw@Sun.COM return (-1);
3428670SJose.Borrego@Sun.COM }
3438670SJose.Borrego@Sun.COM
3448670SJose.Borrego@Sun.COM if (need_lookup) {
3458670SJose.Borrego@Sun.COM user = smb_session_dup_user(sr->session,
34612508Samw@Sun.COM token->tkn_domain_name, token->tkn_account_name);
3478670SJose.Borrego@Sun.COM if (user != NULL) {
34812508Samw@Sun.COM sinfo->ssi_guest = SMB_USER_IS_GUEST(user);
3498670SJose.Borrego@Sun.COM sr->user_cr = user->u_cred;
3508670SJose.Borrego@Sun.COM sr->smb_uid = user->u_uid;
3518670SJose.Borrego@Sun.COM sr->uid_user = user;
35212508Samw@Sun.COM smb_token_free(token);
35312508Samw@Sun.COM return (0);
3548670SJose.Borrego@Sun.COM }
3558670SJose.Borrego@Sun.COM }
3568670SJose.Borrego@Sun.COM
35712508Samw@Sun.COM if (token->tkn_session_key) {
35811963SAfshin.Ardakani@Sun.COM *session_key = smb_srm_zalloc(sr, sizeof (smb_session_key_t));
35912508Samw@Sun.COM bcopy(token->tkn_session_key, *session_key,
3608670SJose.Borrego@Sun.COM sizeof (smb_session_key_t));
3618670SJose.Borrego@Sun.COM }
3628670SJose.Borrego@Sun.COM
36312508Samw@Sun.COM if ((cr = smb_cred_create(token)) == NULL) {
36412508Samw@Sun.COM smb_token_free(token);
36512508Samw@Sun.COM smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_HANDLE);
36612508Samw@Sun.COM return (-1);
3678670SJose.Borrego@Sun.COM }
3688670SJose.Borrego@Sun.COM
36912508Samw@Sun.COM privileges = smb_priv_xlate(token);
37012508Samw@Sun.COM
37112508Samw@Sun.COM user = smb_user_login(sr->session, cr,
37212508Samw@Sun.COM token->tkn_domain_name, token->tkn_account_name,
37312508Samw@Sun.COM token->tkn_flags, privileges, token->tkn_audit_sid);
37412508Samw@Sun.COM
37512508Samw@Sun.COM crfree(cr);
37612508Samw@Sun.COM smb_token_free(token);
3778670SJose.Borrego@Sun.COM
3788670SJose.Borrego@Sun.COM if (user == NULL) {
3798670SJose.Borrego@Sun.COM smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_HANDLE);
38012508Samw@Sun.COM return (-1);
3818670SJose.Borrego@Sun.COM }
3828670SJose.Borrego@Sun.COM
38312508Samw@Sun.COM sinfo->ssi_guest = SMB_USER_IS_GUEST(user);
3848670SJose.Borrego@Sun.COM sr->user_cr = user->u_cred;
3858670SJose.Borrego@Sun.COM sr->smb_uid = user->u_uid;
3868670SJose.Borrego@Sun.COM sr->uid_user = user;
38712508Samw@Sun.COM return (0);
38812508Samw@Sun.COM }
3898670SJose.Borrego@Sun.COM
39012508Samw@Sun.COM /*
39112508Samw@Sun.COM * Allocate a Solaris cred and initialize it based on the access token.
39212508Samw@Sun.COM *
39312508Samw@Sun.COM * If the user can be mapped to a non-ephemeral ID, the cred gid is set
39412508Samw@Sun.COM * to the Solaris user's primary group.
39512508Samw@Sun.COM *
39612508Samw@Sun.COM * If the mapped UID is ephemeral, or the primary group could not be
39712508Samw@Sun.COM * obtained, the cred gid is set to whatever Solaris group is mapped
39812508Samw@Sun.COM * to the token's primary group.
39912508Samw@Sun.COM */
40012508Samw@Sun.COM static cred_t *
smb_cred_create(smb_token_t * token)40112508Samw@Sun.COM smb_cred_create(smb_token_t *token)
40212508Samw@Sun.COM {
40312508Samw@Sun.COM ksid_t ksid;
40412508Samw@Sun.COM ksidlist_t *ksidlist = NULL;
40512508Samw@Sun.COM smb_posix_grps_t *posix_grps;
40612508Samw@Sun.COM cred_t *cr;
40712508Samw@Sun.COM gid_t gid;
40812508Samw@Sun.COM
40912508Samw@Sun.COM ASSERT(token);
41012508Samw@Sun.COM ASSERT(token->tkn_posix_grps);
41112508Samw@Sun.COM posix_grps = token->tkn_posix_grps;
41212508Samw@Sun.COM
41312508Samw@Sun.COM cr = crget();
41412508Samw@Sun.COM ASSERT(cr != NULL);
41512508Samw@Sun.COM
41612508Samw@Sun.COM if (!IDMAP_ID_IS_EPHEMERAL(token->tkn_user.i_id) &&
41712508Samw@Sun.COM (posix_grps->pg_ngrps != 0)) {
41812508Samw@Sun.COM gid = posix_grps->pg_grps[0];
41912508Samw@Sun.COM } else {
42012508Samw@Sun.COM gid = token->tkn_primary_grp.i_id;
42112508Samw@Sun.COM }
42212508Samw@Sun.COM
42312508Samw@Sun.COM if (crsetugid(cr, token->tkn_user.i_id, gid) != 0) {
42412508Samw@Sun.COM crfree(cr);
42512508Samw@Sun.COM return (NULL);
42612508Samw@Sun.COM }
42712508Samw@Sun.COM
42812508Samw@Sun.COM if (crsetgroups(cr, posix_grps->pg_ngrps, posix_grps->pg_grps) != 0) {
42912508Samw@Sun.COM crfree(cr);
43012508Samw@Sun.COM return (NULL);
43112508Samw@Sun.COM }
43212508Samw@Sun.COM
43312508Samw@Sun.COM smb_cred_set_sid(&token->tkn_user, &ksid);
43412508Samw@Sun.COM crsetsid(cr, &ksid, KSID_USER);
43512508Samw@Sun.COM smb_cred_set_sid(&token->tkn_primary_grp, &ksid);
43612508Samw@Sun.COM crsetsid(cr, &ksid, KSID_GROUP);
43712508Samw@Sun.COM smb_cred_set_sid(&token->tkn_owner, &ksid);
43812508Samw@Sun.COM crsetsid(cr, &ksid, KSID_OWNER);
43912508Samw@Sun.COM ksidlist = smb_cred_set_sidlist(&token->tkn_win_grps);
44012508Samw@Sun.COM crsetsidlist(cr, ksidlist);
44112508Samw@Sun.COM
44212508Samw@Sun.COM if (smb_token_query_privilege(token, SE_TAKE_OWNERSHIP_LUID))
44312508Samw@Sun.COM (void) crsetpriv(cr, PRIV_FILE_CHOWN, NULL);
44412508Samw@Sun.COM
44512508Samw@Sun.COM return (cr);
4468670SJose.Borrego@Sun.COM }
44712508Samw@Sun.COM
44812508Samw@Sun.COM /*
44912508Samw@Sun.COM * Initialize the ksid based on the given smb_id_t.
45012508Samw@Sun.COM */
45112508Samw@Sun.COM static void
smb_cred_set_sid(smb_id_t * id,ksid_t * ksid)45212508Samw@Sun.COM smb_cred_set_sid(smb_id_t *id, ksid_t *ksid)
45312508Samw@Sun.COM {
45412508Samw@Sun.COM char sidstr[SMB_SID_STRSZ];
45512508Samw@Sun.COM int rc;
45612508Samw@Sun.COM
45712508Samw@Sun.COM ASSERT(id);
45812508Samw@Sun.COM ASSERT(id->i_sid);
45912508Samw@Sun.COM
46012508Samw@Sun.COM ksid->ks_id = id->i_id;
46112508Samw@Sun.COM smb_sid_tostr(id->i_sid, sidstr);
46212508Samw@Sun.COM rc = smb_sid_splitstr(sidstr, &ksid->ks_rid);
46312508Samw@Sun.COM ASSERT(rc == 0);
46412508Samw@Sun.COM
46512508Samw@Sun.COM ksid->ks_attr = id->i_attrs;
46612508Samw@Sun.COM ksid->ks_domain = ksid_lookupdomain(sidstr);
46712508Samw@Sun.COM }
46812508Samw@Sun.COM
46912508Samw@Sun.COM /*
47012508Samw@Sun.COM * Allocate and initialize the ksidlist based on the access token group list.
47112508Samw@Sun.COM */
47212508Samw@Sun.COM static ksidlist_t *
smb_cred_set_sidlist(smb_ids_t * token_grps)47312508Samw@Sun.COM smb_cred_set_sidlist(smb_ids_t *token_grps)
47412508Samw@Sun.COM {
47512508Samw@Sun.COM int i;
47612508Samw@Sun.COM ksidlist_t *lp;
47712508Samw@Sun.COM
47812508Samw@Sun.COM lp = kmem_zalloc(KSIDLIST_MEM(token_grps->i_cnt), KM_SLEEP);
47912508Samw@Sun.COM lp->ksl_ref = 1;
48012508Samw@Sun.COM lp->ksl_nsid = token_grps->i_cnt;
48112508Samw@Sun.COM lp->ksl_neid = 0;
48212508Samw@Sun.COM
48312508Samw@Sun.COM for (i = 0; i < lp->ksl_nsid; i++) {
48412508Samw@Sun.COM smb_cred_set_sid(&token_grps->i_ids[i], &lp->ksl_sids[i]);
48512508Samw@Sun.COM if (lp->ksl_sids[i].ks_id > IDMAP_WK__MAX_GID)
48612508Samw@Sun.COM lp->ksl_neid++;
48712508Samw@Sun.COM }
48812508Samw@Sun.COM
48912508Samw@Sun.COM return (lp);
49012508Samw@Sun.COM }
49112508Samw@Sun.COM
49212508Samw@Sun.COM /*
49312508Samw@Sun.COM * Convert access token privileges to local definitions.
49412508Samw@Sun.COM */
49512508Samw@Sun.COM static uint32_t
smb_priv_xlate(smb_token_t * token)49612508Samw@Sun.COM smb_priv_xlate(smb_token_t *token)
49712508Samw@Sun.COM {
49812508Samw@Sun.COM uint32_t privileges = 0;
49912508Samw@Sun.COM
50012508Samw@Sun.COM if (smb_token_query_privilege(token, SE_BACKUP_LUID))
50112508Samw@Sun.COM privileges |= SMB_USER_PRIV_BACKUP;
50212508Samw@Sun.COM
50312508Samw@Sun.COM if (smb_token_query_privilege(token, SE_RESTORE_LUID))
50412508Samw@Sun.COM privileges |= SMB_USER_PRIV_RESTORE;
50512508Samw@Sun.COM
50612508Samw@Sun.COM if (smb_token_query_privilege(token, SE_TAKE_OWNERSHIP_LUID))
50712508Samw@Sun.COM privileges |= SMB_USER_PRIV_TAKE_OWNERSHIP;
50812508Samw@Sun.COM
50912508Samw@Sun.COM if (smb_token_query_privilege(token, SE_SECURITY_LUID))
51012508Samw@Sun.COM privileges |= SMB_USER_PRIV_SECURITY;
51112508Samw@Sun.COM
51212508Samw@Sun.COM return (privileges);
51312508Samw@Sun.COM }
514