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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * SMB: session_setup_andx 27 * 28 * This SMB is used to further "Set up" the session normally just 29 * established via the negotiate protocol. 30 * 31 * One primary function is to perform a "user logon" in the case where the 32 * server is in user level security mode. The Uid in the SMB header is set 33 * by the client to be the userid desired for the AccountName and validated 34 * by the AccountPassword. 35 * 36 * If the negotiated protocol is prior to NT LM 0.12, the format of 37 * SMB_COM_SESSION_SETUP_ANDX is: 38 * 39 * Client Request Description 40 * ============================== ===================================== 41 * 42 * UCHAR WordCount; Count of parameter words = 10 43 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none 44 * UCHAR AndXReserved; Reserved (must be 0) 45 * USHORT AndXOffset; Offset to next command WordCount 46 * USHORT MaxBufferSize; Client maximum buffer size 47 * USHORT MaxMpxCount; Actual maximum multiplexed pending 48 * requests 49 * USHORT VcNumber; 0 = first (only), nonzero=additional 50 * VC number 51 * ULONG SessionKey; Session key (valid iff VcNumber != 0) 52 * USHORT PasswordLength; Account password size 53 * ULONG Reserved; Must be 0 54 * USHORT ByteCount; Count of data bytes; min = 0 55 * UCHAR AccountPassword[]; Account Password 56 * STRING AccountName[]; Account Name 57 * STRING PrimaryDomain[]; Client's primary domain 58 * STRING NativeOS[]; Client's native operating system 59 * STRING NativeLanMan[]; Client's native LAN Manager type 60 * 61 * and the response is: 62 * 63 * Server Response Description 64 * ================================== ================================= 65 * 66 * UCHAR WordCount; Count of parameter words = 3 67 * UCHAR AndXCommand; Secondary (X) command; 0xFF = 68 * none 69 * UCHAR AndXReserved; Reserved (must be 0) 70 * USHORT AndXOffset; Offset to next command WordCount 71 * USHORT Action; Request mode: 72 * bit0 = logged in as GUEST 73 * USHORT ByteCount; Count of data bytes 74 * STRING NativeOS[]; Server's native operating system 75 * STRING NativeLanMan[]; Server's native LAN Manager type 76 * STRING PrimaryDomain[]; Server's primary domain 77 * 78 * If the server is in "share level security mode", the account name and 79 * passwd should be ignored by the server. 80 * 81 * If challenge/response authentication is not being used, AccountPassword 82 * should be a null terminated ASCII string with PasswordLength set to the 83 * string size including the null; the password will case insensitive. If 84 * challenge/response authentication is being used (see section 2.10), then 85 * AccountPassword will be the response to the server's challenge, and 86 * PasswordLength should be set to its length. 87 * 88 * The server validates the name and password supplied and if valid, it 89 * registers the user identifier on this session as representing the 90 * specified AccountName. The Uid field in the SMB header will then be 91 * used to validate access on subsequent SMB requests. The SMB requests 92 * where permission checks are required are those which refer to a 93 * symbolically named resource such as SMB_COM_OPEN, SMB_COM_RENAME, 94 * SMB_COM_DELETE, etc.. The value of the Uid is relative to a specific 95 * client/server session so it is possible to have the same Uid value 96 * represent two different users on two different sessions at the server. 97 * 98 * Multiple session setup commands may be sent to register additional users 99 * on this session. If the server receives an additional 100 * SMB_COM_SESSION_SETUP_ANDX, only the Uid, AccountName and 101 * AccountPassword fields need contain valid values (the server MUST ignore 102 * the other fields). 103 * 104 * The client writes the name of its domain in PrimaryDomain if it knows 105 * what the domain name is. If the domain name is unknown, the client 106 * either encodes it as a NULL string, or as a question mark. 107 * 108 * If bit0 of Action is set, this informs the client that although the 109 * server did not recognize the AccountName, it logged the user in as a 110 * guest. This is optional behavior by the server, and in any case one 111 * would ordinarily expect guest privileges to limited. 112 * 113 * Another function of the Session Set Up protocol is to inform the server 114 * of the maximum values which will be utilized by this client. Here 115 * MaxBufferSize is the maximum message size which the client can receive. 116 * Thus although the server may support 16k buffers (as returned in the 117 * SMB_COM_NEGOTIATE response), if the client only has 4k buffers, the 118 * value of MaxBufferSize here would be 4096. The minimum allowable value 119 * for MaxBufferSize is 1024. The SMB_COM_NEGOTIATE response includes the 120 * server buffer size supported. Thus this is the maximum SMB message size 121 * which the client can send to the server. This size may be larger than 122 * the size returned to the server from the client via the 123 * SMB_COM_SESSION_SETUP_AND X protocol which is the maximum SMB message 124 * size which the server may send to the client. Thus if the server's 125 * buffer size were 4k and the client's buffer size were only 2K, the 126 * client could send up to 4k (standard) write requests but must only 127 * request up to 2k for (standard) read requests. 128 * 129 * The field, MaxMpxCount informs the server of the maximum number of 130 * requests which the client will have outstanding to the server 131 * simultaneously (see sections 5.13 and 5.25). 132 * 133 * The VcNumber field specifies whether the client wants this to be the 134 * first VC or an additional VC. If the the SMB_COM_SESSION_SETUP_ANDX 135 * request contains a VcNumber of 0 and other VCs are still connected to 136 * that client, they should be aborted to free any resources held by the 137 * server. This condition could occur if the client was rebooted and 138 * reconnected to the server before the transport level had informed the 139 * server of the previous VC termination. There is more information on 140 * VCs in smb_negotiate.c. 141 * 142 * The values for MaxBufferSize, MaxMpxCount, and VcNumber must be less 143 * than or equal to the maximum values supported by the server as returned 144 * in the SMB_COM_NEGOTIATE response. 145 * 146 * If the negotiated SMB dialect is "NT LM 0.12" or later, the format of 147 * the response SMB is unchanged, but the request is: 148 * 149 * Client Request Description 150 * ============================== ===================================== 151 * 152 * UCHAR WordCount; Count of parameter words = 13 153 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none 154 * UCHAR AndXReserved; Reserved (must be 0) 155 * USHORT AndXOffset; Offset to next command WordCount 156 * USHORT MaxBufferSize; Client's maximum buffer size 157 * USHORT MaxMpxCount; Actual maximum multiplexed pending 158 * requests 159 * USHORT VcNumber; 0 = first (only), nonzero=additional 160 * VC number 161 * ULONG SessionKey; Session key (valid iff VcNumber != 0) 162 * USHORT Account password size, ANSI 163 * CaseInsensitivePasswordLength; 164 * USHORT Account password size, Unicode 165 * CaseSensitivePasswordLength; 166 * ULONG Reserved; must be 0 167 * ULONG Capabilities; Client capabilities 168 * USHORT ByteCount; Count of data bytes; min = 0 169 * UCHAR Account Password, ANSI 170 * CaseInsensitivePassword[]; 171 * UCHAR CaseSensitivePassword[]; Account Password, Unicode 172 * STRING AccountName[]; Account Name, Unicode 173 * STRING PrimaryDomain[]; Client's primary domain, Unicode 174 * STRING NativeOS[]; Client's native operating system, 175 * Unicode 176 * STRING NativeLanMan[]; Client's native LAN Manager type, 177 * Unicode 178 * 179 * The client expresses its capabilities to the server encoded in the 180 * Capabilities field: 181 * 182 * Capability Name Encoding Description 183 * ======================== ========= ================================ 184 * 185 * CAP_UNICODE 0x0004 The client can use UNICODE 186 * strings 187 * CAP_LARGE_FILES 0x0008 The client can deal with files 188 * having 64 bit offsets 189 * CAP_NT_SMBS 0x0010 The client understands the SMBs 190 * introduced with the NT LM 0.12 191 * dialect. Implies CAP_NT_FIND. 192 * CAP_NT_FIND 0x0200 193 * CAP_STATUS32 0x0040 The client can receive 32 bit 194 * errors encoded in Status.Status 195 * CAP_LEVEL_II_OPLOCKS 0x0080 The client understands Level II 196 * oplocks 197 * 198 * The entire message sent and received including the optional ANDX SMB 199 * must fit in the negotiated maximum transfer size. The following are the 200 * only valid SMB commands for AndXCommand for SMB_COM_SESSION_SETUP_ANDX 201 * 202 * SMB_COM_TREE_CONNECT_ANDX SMB_COM_OPEN 203 * SMB_COM_OPEN_ANDX SMB_COM_CREATE 204 * SMB_COM_CREATE_NEW SMB_COM_CREATE_DIRECTORY 205 * SMB_COM_DELETE SMB_COM_DELETE_DIRECTORY 206 * SMB_COM_FIND SMB_COM_FIND_UNIQUE 207 * SMB_COM_COPY SMB_COM_RENAME 208 * SMB_COM_NT_RENAME SMB_COM_CHECK_DIRECTORY 209 * SMB_COM_QUERY_INFORMATION SMB_COM_SET_INFORMATION 210 * SMB_COM_NO_ANDX_COMMAND SMB_COM_OPEN_PRINT_FILE 211 * SMB_COM_GET_PRINT_QUEUE SMB_COM_TRANSACTION 212 * 213 * 4.1.2.1 Errors 214 * 215 * ERRSRV/ERRerror - no NEG_PROT issued 216 * ERRSRV/ERRbadpw - password not correct for given user name 217 * ERRSRV/ERRtoomanyuids - maximum number of users per session exceeded 218 * ERRSRV/ERRnosupport - chaining of this request to the previous one is 219 * not supported 220 */ 221 222 #include <sys/types.h> 223 #include <sys/socket.h> 224 #include <netinet/in.h> 225 #include <smbsrv/smb_incl.h> 226 #include <smbsrv/smb_token.h> 227 #include <smbsrv/smb_door_svc.h> 228 229 smb_sdrc_t 230 smb_pre_session_setup_andx(smb_request_t *sr) 231 { 232 DTRACE_SMB_1(op__SessionSetupX__start, smb_request_t *, sr); 233 return (SDRC_SUCCESS); 234 } 235 236 void 237 smb_post_session_setup_andx(smb_request_t *sr) 238 { 239 DTRACE_SMB_1(op__SessionSetupX__done, smb_request_t *, sr); 240 } 241 242 smb_sdrc_t 243 smb_com_session_setup_andx(smb_request_t *sr) 244 { 245 uint16_t maxbufsize, maxmpxcount, vcnumber = 0; 246 uint32_t sesskey; 247 uint32_t capabilities = 0; 248 char *username = ""; 249 char *userdomain = ""; 250 char *native_os = ""; 251 char *native_lanman = ""; 252 char *hostname = sr->sr_cfg->skc_hostname; 253 char *nbdomain = sr->sr_cfg->skc_nbdomain; 254 char *fqdn = sr->sr_cfg->skc_fqdn; 255 smb_token_t *usr_token = NULL; 256 smb_user_t *user = NULL; 257 int security = sr->sr_cfg->skc_secmode; 258 259 uint16_t ci_pwlen = 0; 260 unsigned char *ci_password = NULL; 261 uint16_t cs_pwlen = 0; 262 unsigned char *cs_password = NULL; 263 264 netr_client_t clnt_info; 265 smb_session_key_t *session_key = NULL; 266 int rc; 267 char ipaddr_buf[INET6_ADDRSTRLEN]; 268 boolean_t known_domain; 269 270 if (sr->session->dialect >= NT_LM_0_12) { 271 rc = smbsr_decode_vwv(sr, "b.wwwwlww4.l", &sr->andx_com, 272 &sr->andx_off, &maxbufsize, &maxmpxcount, &vcnumber, 273 &sesskey, &ci_pwlen, &cs_pwlen, &capabilities); 274 275 if (rc != 0) 276 return (SDRC_ERROR); 277 278 ci_password = kmem_alloc(ci_pwlen + 1, KM_SLEEP); 279 cs_password = kmem_alloc(cs_pwlen + 1, KM_SLEEP); 280 281 /* 282 * The padding between the Native OS and Native LM is a 283 * bit strange. On NT4.0, there is a 2 byte pad between 284 * the OS (Windows NT 1381) and LM (Windows NT 4.0). 285 * On Windows 2000, there is no padding between the OS 286 * (Windows 2000 2195) and LM (Windows 2000 5.0). 287 * 288 * If the padding is removed from this decode string 289 * the NT4.0 LM comes out as an empty string. 290 * 291 * So if the client's native OS is Win NT we consider 292 * the padding otherwise we don't. 293 */ 294 rc = smbsr_decode_data(sr, "%#c#cuuu", 295 sr, 296 ci_pwlen, ci_password, 297 cs_pwlen, cs_password, 298 &username, 299 &userdomain, 300 &native_os); 301 302 if (rc != 0) { 303 kmem_free(ci_password, ci_pwlen + 1); 304 kmem_free(cs_password, cs_pwlen + 1); 305 return (SDRC_ERROR); 306 } 307 308 ci_password[ci_pwlen] = 0; 309 cs_password[cs_pwlen] = 0; 310 311 sr->session->native_os = smbnative_os_value(native_os); 312 313 if (sr->session->native_os == NATIVE_OS_WINNT) 314 rc = smbsr_decode_data(sr, "%,u", sr, &native_lanman); 315 else 316 rc = smbsr_decode_data(sr, "%u", sr, &native_lanman); 317 318 /* 319 * Native Lanman could be null so we really don't care 320 * if above decode fails, but to have a valid value for 321 * the field we set it to Win NT. 322 */ 323 if (rc != 0) 324 native_lanman = "NT LAN Manager 4.0"; 325 326 } else { 327 rc = smbsr_decode_vwv(sr, "b.wwwwlw4.", &sr->andx_com, 328 &sr->andx_off, &maxbufsize, &maxmpxcount, 329 &vcnumber, &sesskey, &ci_pwlen); 330 331 if (rc != 0) 332 return (SDRC_ERROR); 333 334 ci_password = kmem_alloc(ci_pwlen + 1, KM_SLEEP); 335 rc = smbsr_decode_data(sr, "%#c", sr, ci_pwlen, ci_password); 336 if (rc != 0) { 337 kmem_free(ci_password, ci_pwlen + 1); 338 return (SDRC_ERROR); 339 } 340 341 ci_password[ci_pwlen] = 0; 342 343 /* 344 * Despite the CIFS/1.0 spec, the rest of this message is 345 * not always present. We need to try to get the account 346 * name and the primary domain but we don't care about the 347 * the native OS or native LanMan fields. 348 */ 349 if (smbsr_decode_data(sr, "%u", sr, &username) != 0) 350 username = ""; 351 352 if (smbsr_decode_data(sr, "%u", sr, &userdomain) != 0) 353 userdomain = ""; 354 355 sr->session->native_os = NATIVE_OS_UNKNOWN; 356 } 357 358 /* 359 * If the vcnumber is zero, we can discard any 360 * other connections associated with this client. 361 */ 362 sr->session->vcnumber = vcnumber; 363 if (vcnumber == 0) 364 smb_server_reconnection_check(sr->sr_server, sr->session); 365 366 sr->session->smb_msg_size = maxbufsize; 367 368 bzero(&clnt_info, sizeof (netr_client_t)); 369 370 /* 371 * Both local and domain users can be authenticated in 372 * domain mode. Whether a user is local or not is determined 373 * by given domain name in the request. If client does not 374 * specify the domain name, both local and domain 375 * authentications should be tried. The preferred order is to 376 * try the local authentication first. 377 */ 378 known_domain = B_TRUE; 379 if (*userdomain == 0) { 380 userdomain = hostname; 381 if (security == SMB_SECMODE_DOMAIN) 382 known_domain = B_FALSE; 383 } 384 385 if ((cs_pwlen == 0) && 386 (ci_pwlen == 0 || (ci_pwlen == 1 && *ci_password == 0))) { 387 /* anonymous user */ 388 clnt_info.flags |= NETR_CFLG_ANON; 389 username = "nobody"; 390 } else if (*username == '\0') { 391 if (ci_password) 392 kmem_free(ci_password, ci_pwlen + 1); 393 if (cs_password) 394 kmem_free(cs_password, cs_pwlen + 1); 395 smbsr_error(sr, 0, ERRSRV, ERRaccess); 396 return (SDRC_ERROR); 397 } else if (security == SMB_SECMODE_DOMAIN) { 398 /* 399 * If the system is running in domain mode, domain 400 * authentication will be performed only when the client 401 * sends the domain that matches either the NetBIOS name 402 * or FQDN of the domain. Otherwise, local authentication 403 * will be performed. 404 */ 405 if (utf8_strcasecmp(userdomain, nbdomain) == 0 || 406 utf8_strcasecmp(userdomain, fqdn) == 0) 407 clnt_info.flags |= NETR_CFLG_DOMAIN; 408 else 409 clnt_info.flags |= NETR_CFLG_LOCAL; 410 } else if (security == SMB_SECMODE_WORKGRP) { 411 clnt_info.flags |= NETR_CFLG_LOCAL; 412 } 413 414 /* 415 * If the domain is unknown, we are unable to determine 416 * whether the specified user is local or domain until 417 * the authentication has taken place; thus, the user 418 * lookup will be postponed until the user is successfully 419 * authenticated. 420 */ 421 if (known_domain) 422 user = smb_session_dup_user(sr->session, 423 (clnt_info.flags & NETR_CFLG_LOCAL) ? 424 hostname : nbdomain, username); 425 426 if (user == NULL) { 427 cred_t *cr; 428 uint32_t privileges; 429 430 clnt_info.logon_level = NETR_NETWORK_LOGON; 431 clnt_info.domain = userdomain; 432 clnt_info.username = username; 433 clnt_info.workstation = sr->session->workstation; 434 clnt_info.ipaddr = sr->session->ipaddr; 435 clnt_info.local_ipaddr = sr->session->local_ipaddr; 436 clnt_info.challenge_key.challenge_key_val = 437 sr->session->challenge_key; 438 clnt_info.challenge_key.challenge_key_len = 439 sr->session->challenge_len; 440 clnt_info.nt_password.nt_password_val = cs_password; 441 clnt_info.nt_password.nt_password_len = cs_pwlen; 442 clnt_info.lm_password.lm_password_val = ci_password; 443 clnt_info.lm_password.lm_password_len = ci_pwlen; 444 clnt_info.native_os = sr->session->native_os; 445 clnt_info.native_lm = smbnative_lm_value(native_lanman); 446 clnt_info.local_port = sr->session->s_local_port; 447 448 DTRACE_PROBE1(smb__sessionsetup__clntinfo, netr_client_t *, 449 &clnt_info); 450 451 usr_token = smb_upcall_get_token(&clnt_info); 452 453 /* 454 * If the domain is unknown and we fail to authenticate 455 * the user locally, pass-through authentication will be 456 * attempted. 457 */ 458 if (!known_domain) { 459 if (usr_token == NULL) { 460 clnt_info.domain = nbdomain; 461 clnt_info.flags &= ~NETR_CFLG_LOCAL; 462 clnt_info.flags |= NETR_CFLG_DOMAIN; 463 usr_token = smb_upcall_get_token(&clnt_info); 464 } 465 466 /* 467 * Now that the user has successfully been 468 * authenticated, the clnt_info.domain is valid. 469 * Try to see if the user has already logged in from 470 * this session. 471 * 472 * If this is a subsequent login, a duplicate user 473 * instance will be returned. Otherwise, NULL is 474 * returned. 475 */ 476 if (usr_token != NULL) 477 user = smb_session_dup_user(sr->session, 478 clnt_info.domain, username); 479 } 480 481 482 /* authentication fails */ 483 if (usr_token == NULL) { 484 if (ci_password) 485 kmem_free(ci_password, ci_pwlen + 1); 486 if (cs_password) 487 kmem_free(cs_password, cs_pwlen + 1); 488 smbsr_error(sr, 0, ERRSRV, ERRbadpw); 489 return (SDRC_ERROR); 490 } 491 492 if (usr_token->tkn_session_key) { 493 session_key = kmem_alloc(sizeof (smb_session_key_t), 494 KM_SLEEP); 495 (void) memcpy(session_key, usr_token->tkn_session_key, 496 sizeof (smb_session_key_t)); 497 } 498 499 /* first login */ 500 if (user == NULL) { 501 cr = smb_cred_create(usr_token, &privileges); 502 if (cr != NULL) { 503 user = smb_user_login(sr->session, cr, 504 usr_token->tkn_domain_name, 505 usr_token->tkn_account_name, 506 usr_token->tkn_flags, 507 privileges, 508 usr_token->tkn_audit_sid); 509 smb_cred_rele(user->u_cred); 510 511 if (user->u_privcred) 512 smb_cred_rele(user->u_privcred); 513 } 514 } 515 smb_token_free(usr_token); 516 } 517 518 if (ci_password) 519 kmem_free(ci_password, ci_pwlen + 1); 520 521 if (user == NULL) { 522 if (session_key) 523 kmem_free(session_key, sizeof (smb_session_key_t)); 524 if (cs_password) 525 kmem_free(cs_password, cs_pwlen + 1); 526 smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_HANDLE); 527 return (SDRC_ERROR); 528 } 529 530 sr->user_cr = user->u_cred; 531 sr->smb_uid = user->u_uid; 532 sr->uid_user = user; 533 sr->session->capabilities = capabilities; 534 535 /* 536 * Check to see if SMB signing is enable, but if it is already turned 537 * on leave it. 538 * The first authenticated logon provides the MAC key and sequence 539 * numbers for signing all further session on the 540 * same network connection. 541 */ 542 if (!(sr->session->signing.flags & SMB_SIGNING_ENABLED) && 543 (sr->session->secmode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) && 544 (sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) && 545 session_key) 546 smb_sign_init(sr, session_key, (char *)cs_password, cs_pwlen); 547 548 if (cs_password) 549 kmem_free(cs_password, cs_pwlen + 1); 550 551 if (session_key) 552 kmem_free(session_key, sizeof (smb_session_key_t)); 553 554 if (!(sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) && 555 (sr->sr_cfg->skc_signing_required)) { 556 (void) inet_ntop(AF_INET, (char *)&sr->session->ipaddr, 557 ipaddr_buf, sizeof (ipaddr_buf)); 558 cmn_err(CE_NOTE, 559 "SmbSessonSetupX: client %s is not capable of signing", 560 ipaddr_buf); 561 smbsr_error(sr, NT_STATUS_LOGON_FAILURE, 562 ERRDOS, ERROR_LOGON_FAILURE); 563 return (SDRC_ERROR); 564 } 565 566 /* 567 * NT systems use different native OS and native LanMan values 568 * dependent on whether they are acting as a client or a server. 569 * As a server, NT 4.0 responds with the following values: 570 * 571 * NativeOS: Windows NT 4.0 572 * NativeLM: NT LAN Manager 4.0 573 * 574 * We should probably use the same values as NT but this code has 575 * been using the product name and "Windows NT 4.0" for a long time 576 * and I don't know if a change would cause any problems (see the 577 * conditional test below). 578 */ 579 rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%uuu", 580 3, 581 sr->andx_com, 582 -1, /* andx_off */ 583 ((user->u_flags & SMB_USER_FLAG_GUEST) ? 1 : 0), 584 VAR_BCC, 585 sr, 586 "Windows NT 4.0", 587 "NT LAN Manager 4.0", 588 nbdomain); 589 590 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 591 } 592