1/* 2 Unix SMB/CIFS implementation. 3 handle SMBsessionsetup 4 Copyright (C) Andrew Tridgell 1998-2001 5 Copyright (C) Andrew Bartlett 2001 6 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 7 Copyright (C) Luke Howard 2003 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22*/ 23 24#include "includes.h" 25 26uint32 global_client_caps = 0; 27 28/* Foxconn modified start pling 12/29/2011 */ 29/* Fix Android partial auth issue. */ 30//static struct auth_ntlmssp_state *global_ntlmssp_state; 31static struct auth_ntlmssp_state *global_ntlmssp_state = NULL; 32/* Foxconn modified end pling 12/29/2011 */ 33 34/* 35 on a logon error possibly map the error to success if "map to guest" 36 is set approriately 37*/ 38static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **server_info, 39 const char *user, const char *domain) 40{ 41 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) { 42 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || 43 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { 44 DEBUG(3,("No such user %s [%s] - using guest account\n", 45 user, domain)); 46 status = make_server_info_guest(server_info); 47 } 48 } 49 50 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { 51 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { 52 DEBUG(3,("Registered username %s for guest access\n",user)); 53 status = make_server_info_guest(server_info); 54 } 55 } 56 57 return status; 58} 59 60/**************************************************************************** 61 Add the standard 'Samba' signature to the end of the session setup. 62****************************************************************************/ 63 64static int add_signature(char *outbuf, char *p) 65{ 66 char *start = p; 67 fstring lanman; 68 69 fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); 70 71 p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); 72 p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE); 73 p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); 74 75 return PTR_DIFF(p, start); 76} 77 78/**************************************************************************** 79 Send a security blob via a session setup reply. 80****************************************************************************/ 81 82static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, 83 DATA_BLOB blob, NTSTATUS nt_status) 84{ 85 char *p; 86 87 set_message(outbuf,4,0,True); 88 89 nt_status = nt_status_squash(nt_status); 90 SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status)); 91 SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ 92 SSVAL(outbuf, smb_vwv3, blob.length); 93 p = smb_buf(outbuf); 94 95 /* should we cap this? */ 96 memcpy(p, blob.data, blob.length); 97 p += blob.length; 98 99 p += add_signature( outbuf, p ); 100 101 set_message_end(outbuf,p); 102 103 return send_smb(smbd_server_fd(),outbuf); 104} 105 106/**************************************************************************** 107 Do a 'guest' logon, getting back the 108****************************************************************************/ 109 110static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) 111{ 112 struct auth_context *auth_context; 113 auth_usersupplied_info *user_info = NULL; 114 115 NTSTATUS nt_status; 116 unsigned char chal[8]; 117 118 ZERO_STRUCT(chal); 119 120 DEBUG(3,("Got anonymous request\n")); 121 122 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) { 123 return nt_status; 124 } 125 126 if (!make_user_info_guest(&user_info)) { 127 (auth_context->free)(&auth_context); 128 return NT_STATUS_NO_MEMORY; 129 } 130 131 nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info); 132 (auth_context->free)(&auth_context); 133 free_user_info(&user_info); 134 return nt_status; 135} 136 137 138#ifdef HAVE_KRB5 139/**************************************************************************** 140reply to a session setup spnego negotiate packet for kerberos 141****************************************************************************/ 142static int reply_spnego_kerberos(connection_struct *conn, 143 char *inbuf, char *outbuf, 144 int length, int bufsize, 145 DATA_BLOB *secblob) 146{ 147 DATA_BLOB ticket; 148 char *client, *p, *domain; 149 fstring netbios_domain_name; 150 struct passwd *pw; 151 char *user; 152 int sess_vuid; 153 NTSTATUS ret; 154 DATA_BLOB auth_data; 155 DATA_BLOB ap_rep, ap_rep_wrapped, response; 156 auth_serversupplied_info *server_info = NULL; 157 DATA_BLOB session_key = data_blob(NULL, 0); 158 uint8 tok_id[2]; 159 DATA_BLOB nullblob = data_blob(NULL, 0); 160 fstring real_username; 161 162 ZERO_STRUCT(ticket); 163 ZERO_STRUCT(auth_data); 164 ZERO_STRUCT(ap_rep); 165 ZERO_STRUCT(ap_rep_wrapped); 166 ZERO_STRUCT(response); 167 168 if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { 169 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 170 } 171 172 ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key); 173 174 data_blob_free(&ticket); 175 176 if (!NT_STATUS_IS_OK(ret)) { 177 DEBUG(1,("Failed to verify incoming ticket!\n")); 178 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 179 } 180 181 data_blob_free(&auth_data); 182 183 DEBUG(3,("Ticket name is [%s]\n", client)); 184 185 p = strchr_m(client, '@'); 186 if (!p) { 187 DEBUG(3,("Doesn't look like a valid principal\n")); 188 data_blob_free(&ap_rep); 189 data_blob_free(&session_key); 190 SAFE_FREE(client); 191 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 192 } 193 194 *p = 0; 195 if (!strequal(p+1, lp_realm())) { 196 DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); 197 if (!lp_allow_trusted_domains()) { 198 data_blob_free(&ap_rep); 199 data_blob_free(&session_key); 200 SAFE_FREE(client); 201 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 202 } 203 } 204 205 /* this gives a fully qualified user name (ie. with full realm). 206 that leads to very long usernames, but what else can we do? */ 207 208 domain = p+1; 209 210 { 211 /* If we have winbind running, we can (and must) shorten the 212 username by using the short netbios name. Otherwise we will 213 have inconsistent user names. With Kerberos, we get the 214 fully qualified realm, with ntlmssp we get the short 215 name. And even w2k3 does use ntlmssp if you for example 216 connect to an ip address. */ 217 218 struct winbindd_request wb_request; 219 struct winbindd_response wb_response; 220 NSS_STATUS wb_result; 221 222 ZERO_STRUCT(wb_request); 223 ZERO_STRUCT(wb_response); 224 225 DEBUG(10, ("Mapping [%s] to short name\n", domain)); 226 227 fstrcpy(wb_request.domain_name, domain); 228 229 wb_result = winbindd_request(WINBINDD_DOMAIN_INFO, 230 &wb_request, &wb_response); 231 232 if (wb_result == NSS_STATUS_SUCCESS) { 233 234 fstrcpy(netbios_domain_name, 235 wb_response.data.domain_info.name); 236 domain = netbios_domain_name; 237 238 DEBUG(10, ("Mapped to [%s]\n", domain)); 239 } else { 240 DEBUG(3, ("Could not find short name -- winbind " 241 "not running?\n")); 242 } 243 } 244 245 asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); 246 247 /* lookup the passwd struct, create a new user if necessary */ 248 249 map_username( user ); 250 251 pw = smb_getpwnam( user, real_username, True ); 252 253 if (!pw) { 254 DEBUG(1,("Username %s is invalid on this system\n",user)); 255 SAFE_FREE(user); 256 SAFE_FREE(client); 257 data_blob_free(&ap_rep); 258 data_blob_free(&session_key); 259 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 260 } 261 262 /* setup the string used by %U */ 263 264 sub_set_smb_name( real_username ); 265 reload_services(True); 266 267 if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) 268 { 269 DEBUG(1,("make_server_info_from_pw failed!\n")); 270 SAFE_FREE(user); 271 SAFE_FREE(client); 272 data_blob_free(&ap_rep); 273 data_blob_free(&session_key); 274 return ERROR_NT(ret); 275 } 276 277 /* make_server_info_pw does not set the domain. Without this we end up 278 * with the local netbios name in substitutions for %D. */ 279 280 if (server_info->sam_account != NULL) { 281 pdb_set_domain(server_info->sam_account, domain, PDB_SET); 282 } 283 284 /* register_vuid keeps the server info */ 285 /* register_vuid takes ownership of session_key, no need to free after this. 286 A better interface would copy it.... */ 287 sess_vuid = register_vuid(server_info, session_key, nullblob, client); 288 289 SAFE_FREE(user); 290 SAFE_FREE(client); 291 292 if (sess_vuid == -1) { 293 ret = NT_STATUS_LOGON_FAILURE; 294 } else { 295 /* current_user_info is changed on new vuid */ 296 reload_services( True ); 297 298 set_message(outbuf,4,0,True); 299 SSVAL(outbuf, smb_vwv3, 0); 300 301 if (server_info->guest) { 302 SSVAL(outbuf,smb_vwv2,1); 303 } 304 305 SSVAL(outbuf, smb_uid, sess_vuid); 306 307 if (!server_info->guest && !srv_signing_started()) { 308 /* We need to start the signing engine 309 * here but a W2K client sends the old 310 * "BSRSPYL " signature instead of the 311 * correct one. Subsequent packets will 312 * be correct. 313 */ 314 srv_check_sign_mac(inbuf, False); 315 } 316 } 317 318 /* wrap that up in a nice GSS-API wrapping */ 319 if (NT_STATUS_IS_OK(ret)) { 320 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP); 321 } else { 322 ap_rep_wrapped = data_blob(NULL, 0); 323 } 324 response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); 325 reply_sesssetup_blob(conn, outbuf, response, ret); 326 327 data_blob_free(&ap_rep); 328 data_blob_free(&ap_rep_wrapped); 329 data_blob_free(&response); 330 331 return -1; /* already replied */ 332} 333#endif 334 335/**************************************************************************** 336 Send a session setup reply, wrapped in SPNEGO. 337 Get vuid and check first. 338 End the NTLMSSP exchange context if we are OK/complete fail 339***************************************************************************/ 340 341/* Foxconn modified start pling 12/29/2011 */ 342/* Fix Android partial auth issue. */ 343static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf, 344 AUTH_NTLMSSP_STATE **auth_ntlmssp_state, 345 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, 346 BOOL wrap) 347/* Foxconn modified end pling 12/29/2011 */ 348{ 349 BOOL ret; 350 DATA_BLOB response; 351 struct auth_serversupplied_info *server_info = NULL; 352 353 if (NT_STATUS_IS_OK(nt_status)) { 354 server_info = (*auth_ntlmssp_state)->server_info; 355 } else { 356 nt_status = do_map_to_guest(nt_status, 357 &server_info, 358 (*auth_ntlmssp_state)->ntlmssp_state->user, 359 (*auth_ntlmssp_state)->ntlmssp_state->domain); 360 } 361 362 if (NT_STATUS_IS_OK(nt_status)) { 363 int sess_vuid; 364 DATA_BLOB nullblob = data_blob(NULL, 0); 365 DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); 366 367 /* register_vuid keeps the server info */ 368 sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); 369 (*auth_ntlmssp_state)->server_info = NULL; 370 371 if (sess_vuid == -1) { 372 nt_status = NT_STATUS_LOGON_FAILURE; 373 } else { 374 375 /* current_user_info is changed on new vuid */ 376 reload_services( True ); 377 378 set_message(outbuf,4,0,True); 379 SSVAL(outbuf, smb_vwv3, 0); 380 381 if (server_info->guest) { 382 SSVAL(outbuf,smb_vwv2,1); 383 } 384 385 SSVAL(outbuf,smb_uid,sess_vuid); 386 387 if (!server_info->guest && !srv_signing_started()) { 388 /* We need to start the signing engine 389 * here but a W2K client sends the old 390 * "BSRSPYL " signature instead of the 391 * correct one. Subsequent packets will 392 * be correct. 393 */ 394 395 srv_check_sign_mac(inbuf, False); 396 } 397 } 398 } 399 400 /* Foxconn modified start pling 12/29/2011 */ 401 /* Fix Android partial auth issue. */ 402 if (wrap) { 403 response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP); 404 } else { 405 response = *ntlmssp_blob; 406 } 407 ret = reply_sesssetup_blob(conn, outbuf, response, nt_status); 408 if (wrap) 409 data_blob_free(&response); 410 /* Foxconn modified end pling 12/29/2011 */ 411 412 /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us, 413 and the other end, that we are not finished yet. */ 414 415 if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 416 auth_ntlmssp_end(auth_ntlmssp_state); 417 } 418 419 return ret; 420} 421 422/**************************************************************************** 423 Reply to a session setup spnego negotiate packet. 424****************************************************************************/ 425 426static int reply_spnego_negotiate(connection_struct *conn, 427 char *inbuf, 428 char *outbuf, 429 int length, int bufsize, 430 DATA_BLOB blob1) 431{ 432 char *OIDs[ASN1_MAX_OIDS]; 433 DATA_BLOB secblob; 434 int i; 435 DATA_BLOB chal; 436 BOOL got_kerberos = False; 437 NTSTATUS nt_status; 438 439 /* parse out the OIDs and the first sec blob */ 440 if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { 441 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 442 } 443 444 /* only look at the first OID for determining the mechToken -- 445 accoirding to RFC2478, we should choose the one we want 446 and renegotiate, but i smell a client bug here.. 447 448 Problem observed when connecting to a member (samba box) 449 of an AD domain as a user in a Samba domain. Samba member 450 server sent back krb5/mskrb5/ntlmssp as mechtypes, but the 451 client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an 452 NTLMSSP mechtoken. --jerry */ 453 454 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || 455 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { 456 got_kerberos = True; 457 } 458 459 for (i=0;OIDs[i];i++) { 460 DEBUG(3,("Got OID %s\n", OIDs[i])); 461 free(OIDs[i]); 462 } 463 DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length)); 464 465#ifdef HAVE_KRB5 466 if (got_kerberos && (SEC_ADS == lp_security())) { 467 int ret = reply_spnego_kerberos(conn, inbuf, outbuf, 468 length, bufsize, &secblob); 469 data_blob_free(&secblob); 470 return ret; 471 } 472#endif 473 474 if (global_ntlmssp_state) { 475 auth_ntlmssp_end(&global_ntlmssp_state); 476 } 477 478 nt_status = auth_ntlmssp_start(&global_ntlmssp_state); 479 if (!NT_STATUS_IS_OK(nt_status)) { 480 return ERROR_NT(nt_status); 481 } 482 483 nt_status = auth_ntlmssp_update(global_ntlmssp_state, 484 secblob, &chal); 485 486 data_blob_free(&secblob); 487 488 /* Foxconn modified start pling 12/29/2011 */ 489 /* Fix Android partial auth issue. */ 490 reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, 491 &chal, nt_status, True); 492 /* Foxconn modified end pling 12/29/2011 */ 493 494 data_blob_free(&chal); 495 496 /* already replied */ 497 return -1; 498} 499 500/**************************************************************************** 501 Reply to a session setup spnego auth packet. 502****************************************************************************/ 503 504static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, 505 int length, int bufsize, 506 DATA_BLOB blob1) 507{ 508 DATA_BLOB auth, auth_reply; 509 NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; 510 511 if (!spnego_parse_auth(blob1, &auth)) { 512#if 0 513 file_save("auth.dat", blob1.data, blob1.length); 514#endif 515 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 516 } 517 518 if (!global_ntlmssp_state) { 519 /* auth before negotiatiate? */ 520 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 521 } 522 523 nt_status = auth_ntlmssp_update(global_ntlmssp_state, 524 auth, &auth_reply); 525 526 data_blob_free(&auth); 527 528 /* Foxconn modified start pling 12/29/2011 */ 529 /* Fix Android partial auth issue. */ 530 reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, 531 &auth_reply, nt_status, True); 532 /* Foxconn modified start pling 12/29/2011 */ 533 534 data_blob_free(&auth_reply); 535 536 /* and tell smbd that we have already replied to this packet */ 537 return -1; 538} 539 540/**************************************************************************** 541 Reply to a session setup command. 542****************************************************************************/ 543 544static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, 545 char *outbuf, 546 int length,int bufsize) 547{ 548 uint8 *p; 549 DATA_BLOB blob1; 550 int ret; 551 size_t bufrem; 552 fstring native_os, native_lanman, primary_domain; 553 char *p2; 554 uint16 data_blob_len = SVAL(inbuf, smb_vwv7); 555 enum remote_arch_types ra_type = get_remote_arch(); 556 557 DEBUG(3,("Doing spnego session setup\n")); 558 559 if (global_client_caps == 0) { 560 global_client_caps = IVAL(inbuf,smb_vwv10); 561 562 if (!(global_client_caps & CAP_STATUS32)) { 563 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); 564 } 565 566 } 567 568 p = (uint8 *)smb_buf(inbuf); 569 570 if (data_blob_len == 0) { 571 /* an invalid request */ 572 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 573 } 574 575 bufrem = smb_bufrem(inbuf, p); 576 /* pull the spnego blob */ 577 blob1 = data_blob(p, MIN(bufrem, data_blob_len)); 578 579#if 0 580 file_save("negotiate.dat", blob1.data, blob1.length); 581#endif 582 583 p2 = inbuf + smb_vwv13 + data_blob_len; 584 p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE); 585 p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE); 586 p2 += srvstr_pull_buf(inbuf, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE); 587 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", 588 native_os, native_lanman, primary_domain)); 589 590 if ( ra_type == RA_WIN2K ) { 591 /* Windows 2003 doesn't set the native lanman string, 592 but does set primary domain which is a bug I think */ 593 594 if ( !strlen(native_lanman) ) 595 ra_lanman_string( primary_domain ); 596 else 597 ra_lanman_string( native_lanman ); 598 } 599 600 if (blob1.data[0] == ASN1_APPLICATION(0)) { 601 /* its a negTokenTarg packet */ 602 ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1); 603 data_blob_free(&blob1); 604 return ret; 605 } 606 607 if (blob1.data[0] == ASN1_CONTEXT(1)) { 608 /* its a auth packet */ 609 ret = reply_spnego_auth(conn, inbuf, outbuf, length, bufsize, blob1); 610 data_blob_free(&blob1); 611 return ret; 612 } 613 614 /* Foxconn modified start pling 12/29/2011 */ 615 /* Fix Android partial auth issue. 616 * Port from Samba 3.0.24 (used by WNDR3800) */ 617 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) { 618 DATA_BLOB chal; 619 NTSTATUS nt_status; 620 if (!global_ntlmssp_state) { 621 nt_status = auth_ntlmssp_start(&global_ntlmssp_state); 622 if (!NT_STATUS_IS_OK(nt_status)) { 623 return ERROR_NT(nt_status_squash(nt_status)); 624 } 625 } 626 627 nt_status = auth_ntlmssp_update(global_ntlmssp_state, 628 blob1, &chal); 629 630 data_blob_free(&blob1); 631 632 reply_spnego_ntlmssp(conn, inbuf, outbuf, 633 &global_ntlmssp_state, 634 &chal, nt_status, False); 635 data_blob_free(&chal); 636 return -1; 637 } 638 /* Foxconn added end pling 12/29/2011 */ 639 640 /* what sort of packet is this? */ 641 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n")); 642 643 data_blob_free(&blob1); 644 645 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 646} 647 648/**************************************************************************** 649 On new VC == 0, shutdown *all* old connections and users. 650 It seems that only NT4.x does this. At W2K and above (XP etc.). 651 a new session setup with VC==0 is ignored. 652****************************************************************************/ 653 654static void setup_new_vc_session(void) 655{ 656 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n")); 657#if 0 658 conn_close_all(); 659 invalidate_all_vuids(); 660#endif 661} 662 663/**************************************************************************** 664 Reply to a session setup command. 665****************************************************************************/ 666 667int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, 668 int length,int bufsize) 669{ 670 int sess_vuid; 671 int smb_bufsize; 672 DATA_BLOB lm_resp; 673 DATA_BLOB nt_resp; 674 DATA_BLOB plaintext_password; 675 fstring user; 676 fstring sub_user; /* Sainitised username for substituion */ 677 fstring domain; 678 fstring native_os; 679 fstring native_lanman; 680 fstring primary_domain; 681 static BOOL done_sesssetup = False; 682 extern BOOL global_encrypted_passwords_negotiated; 683 extern BOOL global_spnego_negotiated; 684 extern enum protocol_types Protocol; 685 extern int max_send; 686 687 auth_usersupplied_info *user_info = NULL; 688 extern struct auth_context *negprot_global_auth_context; 689 auth_serversupplied_info *server_info = NULL; 690 691 NTSTATUS nt_status; 692 693 BOOL doencrypt = global_encrypted_passwords_negotiated; 694 695 DATA_BLOB session_key; 696 697 START_PROFILE(SMBsesssetupX); 698 699 ZERO_STRUCT(lm_resp); 700 ZERO_STRUCT(nt_resp); 701 ZERO_STRUCT(plaintext_password); 702 703 DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2))); 704 705 /* a SPNEGO session setup has 12 command words, whereas a normal 706 NT1 session setup has 13. See the cifs spec. */ 707 if (CVAL(inbuf, smb_wct) == 12 && 708 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { 709 if (!global_spnego_negotiated) { 710 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n")); 711 return ERROR_NT(NT_STATUS_UNSUCCESSFUL); 712 } 713 714 if (SVAL(inbuf,smb_vwv4) == 0) { 715 setup_new_vc_session(); 716 } 717 return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); 718 } 719 720 smb_bufsize = SVAL(inbuf,smb_vwv2); 721 722 if (Protocol < PROTOCOL_NT1) { 723 uint16 passlen1 = SVAL(inbuf,smb_vwv7); 724 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) { 725 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 726 } 727 728 if (doencrypt) { 729 lm_resp = data_blob(smb_buf(inbuf), passlen1); 730 } else { 731 plaintext_password = data_blob(smb_buf(inbuf), passlen1+1); 732 /* Ensure null termination */ 733 plaintext_password.data[passlen1] = 0; 734 } 735 736 srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE); 737 *domain = 0; 738 739 } else { 740 uint16 passlen1 = SVAL(inbuf,smb_vwv7); 741 uint16 passlen2 = SVAL(inbuf,smb_vwv8); 742 enum remote_arch_types ra_type = get_remote_arch(); 743 char *p = smb_buf(inbuf); 744 char *save_p = smb_buf(inbuf); 745 uint16 byte_count; 746 747 748 if(global_client_caps == 0) { 749 global_client_caps = IVAL(inbuf,smb_vwv11); 750 751 if (!(global_client_caps & CAP_STATUS32)) { 752 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); 753 } 754 755 /* client_caps is used as final determination if client is NT or Win95. 756 This is needed to return the correct error codes in some 757 circumstances. 758 */ 759 760 if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) { 761 if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) { 762 set_remote_arch( RA_WIN95); 763 } 764 } 765 } 766 767 if (!doencrypt) { 768 /* both Win95 and WinNT stuff up the password lengths for 769 non-encrypting systems. Uggh. 770 771 if passlen1==24 its a win95 system, and its setting the 772 password length incorrectly. Luckily it still works with the 773 default code because Win95 will null terminate the password 774 anyway 775 776 if passlen1>0 and passlen2>0 then maybe its a NT box and its 777 setting passlen2 to some random value which really stuffs 778 things up. we need to fix that one. */ 779 780 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1) 781 passlen2 = 0; 782 } 783 784 /* check for nasty tricks */ 785 if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) { 786 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 787 } 788 789 if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) { 790 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 791 } 792 793 /* Save the lanman2 password and the NT md4 password. */ 794 795 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) { 796 doencrypt = False; 797 } 798 799 if (doencrypt) { 800 lm_resp = data_blob(p, passlen1); 801 nt_resp = data_blob(p+passlen1, passlen2); 802 } else { 803 pstring pass; 804 BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS; 805 806#if 0 807 /* This was the previous fix. Not sure if it's still valid. JRA. */ 808 if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) { 809 /* NT4.0 stuffs up plaintext unicode password lengths... */ 810 srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1, 811 sizeof(pass), passlen1, STR_TERMINATE); 812#endif 813 814 if (unic && (passlen2 == 0) && passlen1) { 815 /* Only a ascii plaintext password was sent. */ 816 srvstr_pull(inbuf, pass, smb_buf(inbuf), sizeof(pass), 817 passlen1, STR_TERMINATE|STR_ASCII); 818 } else { 819 srvstr_pull(inbuf, pass, smb_buf(inbuf), 820 sizeof(pass), unic ? passlen2 : passlen1, 821 STR_TERMINATE); 822 } 823 plaintext_password = data_blob(pass, strlen(pass)+1); 824 } 825 826 p += passlen1 + passlen2; 827 p += srvstr_pull_buf(inbuf, user, p, sizeof(user), STR_TERMINATE); 828 p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE); 829 p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE); 830 p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE); 831 832 /* not documented or decoded by Ethereal but there is one more string 833 in the extra bytes which is the same as the PrimaryDomain when using 834 extended security. Windows NT 4 and 2003 use this string to store 835 the native lanman string. Windows 9x does not include a string here 836 at all so we have to check if we have any extra bytes left */ 837 838 byte_count = SVAL(inbuf, smb_vwv13); 839 if ( PTR_DIFF(p, save_p) < byte_count) 840 p += srvstr_pull_buf(inbuf, primary_domain, p, sizeof(primary_domain), STR_TERMINATE); 841 else 842 fstrcpy( primary_domain, "null" ); 843 844 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", 845 domain, native_os, native_lanman, primary_domain)); 846 847 if ( ra_type == RA_WIN2K ) { 848 if ( strlen(native_lanman) == 0 ) 849 ra_lanman_string( primary_domain ); 850 else 851 ra_lanman_string( native_lanman ); 852 } 853 854 } 855 856 if (SVAL(inbuf,smb_vwv4) == 0) { 857 setup_new_vc_session(); 858 } 859 860 /* Foxconn added start pling 11/30/2009 */ 861 /*If all shared folders are 'All - no password', 862 then no need to login for "HTTP", "FTP" or samba.*/ 863 FILE *fp = NULL; 864 fp = fopen("/tmp/all_no_password","r"); 865 if (fp != NULL) { 866 fclose(fp); 867 DEBUG(0, ("all_no_password, sesssetup.c\n")); 868 if (strcmp(user, "guest") && strcmp(user, "admin")) 869 fstrcpy(user, "guest"); 870 } 871 /* Foxconn added end pling 11/30/2009 */ 872 873 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name())); 874 875 if (*user) { 876 if (global_spnego_negotiated) { 877 878 /* This has to be here, because this is a perfectly valid behaviour for guest logons :-( */ 879 880 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n")); 881 return ERROR_NT(NT_STATUS_UNSUCCESSFUL); 882 } 883 fstrcpy(sub_user, user); 884 885 /* setup the string used by %U */ 886 sub_set_smb_name(user); 887 } else { 888 fstrcpy(sub_user, lp_guestaccount()); 889 } 890 891 sub_set_smb_name(sub_user); 892 893 reload_services(True); 894 895 if (lp_security() == SEC_SHARE) { 896 /* in share level we should ignore any passwords */ 897 898 data_blob_free(&lm_resp); 899 data_blob_free(&nt_resp); 900 data_blob_clear_free(&plaintext_password); 901 902 map_username(sub_user); 903 add_session_user(sub_user); 904 /* Then force it to null for the benfit of the code below */ 905 *user = 0; 906 } 907 908 if (!*user) { 909 910 nt_status = check_guest_password(&server_info); 911 912 } else if (doencrypt) { 913 if (!negprot_global_auth_context) { 914 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n")); 915 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 916 } 917 nt_status = make_user_info_for_reply_enc(&user_info, user, domain, 918 lm_resp, nt_resp); 919 if (NT_STATUS_IS_OK(nt_status)) { 920 nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context, 921 user_info, 922 &server_info); 923 } 924 } else { 925 struct auth_context *plaintext_auth_context = NULL; 926 const uint8 *chal; 927 if (NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) { 928 chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context); 929 930 if (!make_user_info_for_reply(&user_info, 931 user, domain, chal, 932 plaintext_password)) { 933 nt_status = NT_STATUS_NO_MEMORY; 934 } 935 936 if (NT_STATUS_IS_OK(nt_status)) { 937 nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context, 938 user_info, 939 &server_info); 940 941 (plaintext_auth_context->free)(&plaintext_auth_context); 942 } 943 } 944 } 945 946 free_user_info(&user_info); 947 948 if (!NT_STATUS_IS_OK(nt_status)) { 949 nt_status = do_map_to_guest(nt_status, &server_info, user, domain); 950 } 951 952 if (!NT_STATUS_IS_OK(nt_status)) { 953 data_blob_free(&nt_resp); 954 data_blob_free(&lm_resp); 955 data_blob_clear_free(&plaintext_password); 956 return ERROR_NT(nt_status_squash(nt_status)); 957 } 958 959 if (server_info->user_session_key.data) { 960 session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length); 961 } else { 962 session_key = data_blob(NULL, 0); 963 } 964 965 data_blob_clear_free(&plaintext_password); 966 967 /* it's ok - setup a reply */ 968 set_message(outbuf,3,0,True); 969 if (Protocol >= PROTOCOL_NT1) { 970 char *p = smb_buf( outbuf ); 971 p += add_signature( outbuf, p ); 972 set_message_end( outbuf, p ); 973 /* perhaps grab OS version here?? */ 974 } 975 976 if (server_info->guest) { 977 SSVAL(outbuf,smb_vwv2,1); 978 } 979 980 /* register the name and uid as being validated, so further connections 981 to a uid can get through without a password, on the same VC */ 982 983 /* register_vuid keeps the server info */ 984 sess_vuid = register_vuid(server_info, session_key, nt_resp.data ? nt_resp : lm_resp, sub_user); 985 data_blob_free(&nt_resp); 986 data_blob_free(&lm_resp); 987 988 if (sess_vuid == -1) { 989 return ERROR_NT(NT_STATUS_LOGON_FAILURE); 990 } 991 992 /* current_user_info is changed on new vuid */ 993 reload_services( True ); 994 995 if (!server_info->guest && !srv_signing_started() && !srv_check_sign_mac(inbuf, True)) { 996 exit_server("reply_sesssetup_and_X: bad smb signature"); 997 } 998 999 SSVAL(outbuf,smb_uid,sess_vuid); 1000 SSVAL(inbuf,smb_uid,sess_vuid); 1001 1002 if (!done_sesssetup) 1003 max_send = MIN(max_send,smb_bufsize); 1004 1005 done_sesssetup = True; 1006 1007 END_PROFILE(SMBsesssetupX); 1008 return chain_reply(inbuf,outbuf,length,bufsize); 1009} 1010