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 2016 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_1(op__SessionSetupX__start, smb_request_t *, sr); 193 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 194 } 195 196 void 197 smb_post_session_setup_andx(smb_request_t *sr) 198 { 199 smb_arg_sessionsetup_t *sinfo = sr->sr_ssetup; 200 201 DTRACE_SMB_1(op__SessionSetupX__done, 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 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 239 if (!smb_oplock_levelII) 240 sr->session->capabilities &= ~CAP_LEVEL_II_OPLOCKS; 241 242 sr->session->native_os = sinfo->ssi_native_os; 243 sr->session->native_lm = sinfo->ssi_native_lm; 244 } 245 246 /* RejectUnencryptedAccess precludes SMB1 access */ 247 if (sr->sr_server->sv_cfg.skc_encrypt == SMB_CONFIG_REQUIRED) { 248 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 249 ERRDOS, ERROR_ACCESS_DENIED); 250 return (SDRC_ERROR); 251 } 252 253 /* 254 * The "meat" of authentication happens here. 255 */ 256 if (sinfo->ssi_type == SMB_SSNSETUP_NTLM012_EXTSEC) 257 status = smb_authenticate_ext(sr); 258 else 259 status = smb_authenticate_old(sr); 260 261 switch (status) { 262 263 case NT_STATUS_SUCCESS: 264 break; 265 266 /* 267 * This is not really an error, but tells the client 268 * it should send another session setup request. 269 */ 270 case NT_STATUS_MORE_PROCESSING_REQUIRED: 271 smbsr_error(sr, status, 0, 0); 272 break; 273 274 case NT_STATUS_ACCESS_DENIED: 275 smbsr_error(sr, status, ERRDOS, ERROR_ACCESS_DENIED); 276 return (SDRC_ERROR); 277 278 case NT_STATUS_TOO_MANY_SESSIONS: 279 smbsr_error(sr, status, ERRSRV, ERRtoomanyuids); 280 return (SDRC_ERROR); 281 282 case NT_STATUS_NO_LOGON_SERVERS: 283 smbsr_error(sr, status, ERRDOS, ERROR_NO_LOGON_SERVERS); 284 return (SDRC_ERROR); 285 286 case NT_STATUS_NETLOGON_NOT_STARTED: 287 smbsr_error(sr, status, ERRDOS, ERROR_NETLOGON_NOT_STARTED); 288 return (SDRC_ERROR); 289 290 case NT_STATUS_USER_SESSION_DELETED: 291 smbsr_error(sr, status, ERRSRV, ERRbaduid); 292 return (SDRC_ERROR); 293 294 case NT_STATUS_INSUFF_SERVER_RESOURCES: 295 smbsr_error(sr, status, ERRSRV, ERRnoresource); 296 return (SDRC_ERROR); 297 298 case NT_STATUS_INTERNAL_ERROR: 299 default: 300 smbsr_error(sr, status, ERRSRV, ERRsrverror); 301 return (SDRC_ERROR); 302 303 } 304 305 action = SMB_USER_IS_GUEST(sr->uid_user) ? 1 : 0; 306 307 switch (sinfo->ssi_type) { 308 309 default: 310 case SMB_SSNSETUP_PRE_NTLM012: 311 case SMB_SSNSETUP_NTLM012_NOEXT: 312 313 rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu", 314 3, 315 sr->andx_com, 316 -1, /* andx_off */ 317 action, 318 VAR_BCC, 319 sr, 320 sr->sr_cfg->skc_native_os, 321 sr->sr_cfg->skc_native_lm, 322 sr->sr_cfg->skc_nbdomain); 323 break; 324 325 case SMB_SSNSETUP_NTLM012_EXTSEC: 326 327 rc = smbsr_encode_result(sr, 4, VAR_BCC, "bb.wwww%#cuuu", 328 4, 329 sr->andx_com, 330 -1, /* andx_off */ 331 action, 332 sinfo->ssi_oseclen, 333 VAR_BCC, 334 sr, 335 sinfo->ssi_oseclen, 336 sinfo->ssi_osecblob, 337 sr->sr_cfg->skc_native_os, 338 sr->sr_cfg->skc_native_lm, 339 sr->sr_cfg->skc_nbdomain); 340 break; 341 } 342 343 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 344 }