Changeset 745 for trunk/server/source3/smbd/smb2_sesssetup.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/smbd/smb2_sesssetup.c
r414 r745 4 4 5 5 Copyright (C) Stefan Metzmacher 2009 6 Copyright (C) Jeremy Allison 2010 6 7 7 8 This program is free software; you can redistribute it and/or modify … … 20 21 21 22 #include "includes.h" 23 #include "smbd/smbd.h" 22 24 #include "smbd/globals.h" 23 25 #include "../libcli/smb/smb_common.h" 24 26 #include "../libcli/auth/spnego.h" 25 26 static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, 27 #include "../libcli/auth/ntlmssp.h" 28 #include "ntlmssp_wrap.h" 29 #include "../librpc/gen_ndr/krb5pac.h" 30 #include "libads/kerberos_proto.h" 31 #include "../lib/util/asn1.h" 32 #include "auth.h" 33 34 static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req, 27 35 uint64_t in_session_id, 28 36 uint8_t in_security_mode, … … 32 40 uint64_t *out_session_id); 33 41 34 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request * req)42 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *smb2req) 35 43 { 36 44 const uint8_t *inhdr; 37 45 const uint8_t *inbody; 38 int i = req->current_idx;46 int i = smb2req->current_idx; 39 47 uint8_t *outhdr; 40 48 DATA_BLOB outbody; … … 53 61 NTSTATUS status; 54 62 55 inhdr = (const uint8_t *) req->in.vector[i+0].iov_base;56 57 if ( req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {58 return smbd_smb2_request_error( req, NT_STATUS_INVALID_PARAMETER);59 } 60 61 inbody = (const uint8_t *) req->in.vector[i+1].iov_base;63 inhdr = (const uint8_t *)smb2req->in.vector[i+0].iov_base; 64 65 if (smb2req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) { 66 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER); 67 } 68 69 inbody = (const uint8_t *)smb2req->in.vector[i+1].iov_base; 62 70 63 71 body_size = SVAL(inbody, 0x00); 64 72 if (body_size != expected_body_size) { 65 return smbd_smb2_request_error( req, NT_STATUS_INVALID_PARAMETER);73 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER); 66 74 } 67 75 … … 70 78 71 79 if (in_security_offset != (SMB2_HDR_BODY + (body_size & 0xFFFFFFFE))) { 72 return smbd_smb2_request_error( req, NT_STATUS_INVALID_PARAMETER);73 } 74 75 if (in_security_length > req->in.vector[i+2].iov_len) {76 return smbd_smb2_request_error( req, NT_STATUS_INVALID_PARAMETER);80 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER); 81 } 82 83 if (in_security_length > smb2req->in.vector[i+2].iov_len) { 84 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER); 77 85 } 78 86 79 87 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID); 80 88 in_security_mode = CVAL(inbody, 0x03); 81 in_security_buffer.data = (uint8_t *) req->in.vector[i+2].iov_base;89 in_security_buffer.data = (uint8_t *)smb2req->in.vector[i+2].iov_base; 82 90 in_security_buffer.length = in_security_length; 83 91 84 status = smbd_smb2_session_setup( req,92 status = smbd_smb2_session_setup(smb2req, 85 93 in_session_id, 86 94 in_security_mode, … … 92 100 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 93 101 status = nt_status_squash(status); 94 return smbd_smb2_request_error( req, status);102 return smbd_smb2_request_error(smb2req, status); 95 103 } 96 104 97 105 out_security_offset = SMB2_HDR_BODY + 0x08; 98 106 99 outhdr = (uint8_t *) req->out.vector[i].iov_base;100 101 outbody = data_blob_talloc( req->out.vector, NULL, 0x08);107 outhdr = (uint8_t *)smb2req->out.vector[i].iov_base; 108 109 outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x08); 102 110 if (outbody.data == NULL) { 103 return smbd_smb2_request_error( req, NT_STATUS_NO_MEMORY);111 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY); 104 112 } 105 113 … … 116 124 outdyn = out_security_buffer; 117 125 118 return smbd_smb2_request_done_ex( req, status, outbody, &outdyn,126 return smbd_smb2_request_done_ex(smb2req, status, outbody, &outdyn, 119 127 __location__); 120 128 } … … 142 150 } 143 151 144 static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, 152 static NTSTATUS setup_ntlmssp_session_info(struct smbd_smb2_session *session, 153 NTSTATUS status) 154 { 155 if (NT_STATUS_IS_OK(status)) { 156 status = auth_ntlmssp_steal_session_info(session, 157 session->auth_ntlmssp_state, 158 &session->session_info); 159 } else { 160 /* Note that this session_info won't have a session 161 * key. But for map to guest, that's exactly the right 162 * thing - we can't reasonably guess the key the 163 * client wants, as the password was wrong */ 164 status = do_map_to_guest(status, 165 &session->session_info, 166 auth_ntlmssp_get_username(session->auth_ntlmssp_state), 167 auth_ntlmssp_get_domain(session->auth_ntlmssp_state)); 168 } 169 return status; 170 } 171 172 #ifdef HAVE_KRB5 173 static NTSTATUS smbd_smb2_session_setup_krb5(struct smbd_smb2_session *session, 174 struct smbd_smb2_request *smb2req, 175 uint8_t in_security_mode, 176 const DATA_BLOB *secblob, 177 const char *mechOID, 178 uint16_t *out_session_flags, 179 DATA_BLOB *out_security_buffer, 180 uint64_t *out_session_id) 181 { 182 DATA_BLOB ap_rep = data_blob_null; 183 DATA_BLOB ap_rep_wrapped = data_blob_null; 184 DATA_BLOB ticket = data_blob_null; 185 DATA_BLOB session_key = data_blob_null; 186 DATA_BLOB secblob_out = data_blob_null; 187 uint8 tok_id[2]; 188 struct PAC_LOGON_INFO *logon_info = NULL; 189 char *principal = NULL; 190 char *user = NULL; 191 char *domain = NULL; 192 struct passwd *pw = NULL; 193 NTSTATUS status; 194 char *real_username; 195 fstring tmp; 196 bool username_was_mapped = false; 197 bool map_domainuser_to_guest = false; 198 199 if (!spnego_parse_krb5_wrap(talloc_tos(), *secblob, &ticket, tok_id)) { 200 status = NT_STATUS_LOGON_FAILURE; 201 goto fail; 202 } 203 204 status = ads_verify_ticket(smb2req, lp_realm(), 0, &ticket, 205 &principal, &logon_info, &ap_rep, 206 &session_key, true); 207 208 if (!NT_STATUS_IS_OK(status)) { 209 DEBUG(1,("smb2: Failed to verify incoming ticket with error %s!\n", 210 nt_errstr(status))); 211 if (!NT_STATUS_EQUAL(status, NT_STATUS_TIME_DIFFERENCE_AT_DC)) { 212 status = NT_STATUS_LOGON_FAILURE; 213 } 214 goto fail; 215 } 216 217 status = get_user_from_kerberos_info(talloc_tos(), 218 smb2req->sconn->client_id.name, 219 principal, logon_info, 220 &username_was_mapped, 221 &map_domainuser_to_guest, 222 &user, &domain, 223 &real_username, &pw); 224 if (!NT_STATUS_IS_OK(status)) { 225 goto fail; 226 } 227 228 /* save the PAC data if we have it */ 229 if (logon_info) { 230 netsamlogon_cache_store(user, &logon_info->info3); 231 } 232 233 /* setup the string used by %U */ 234 sub_set_smb_name(real_username); 235 236 /* reload services so that the new %U is taken into account */ 237 reload_services(smb2req->sconn->msg_ctx, smb2req->sconn->sock, true); 238 239 status = make_server_info_krb5(session, 240 user, domain, real_username, pw, 241 logon_info, map_domainuser_to_guest, 242 &session->session_info); 243 if (!NT_STATUS_IS_OK(status)) { 244 DEBUG(1, ("smb2: make_server_info_krb5 failed\n")); 245 goto fail; 246 } 247 248 249 session->session_info->nss_token |= username_was_mapped; 250 251 /* we need to build the token for the user. make_session_info_guest() 252 already does this */ 253 254 if (!session->session_info->security_token ) { 255 status = create_local_token(session->session_info); 256 if (!NT_STATUS_IS_OK(status)) { 257 DEBUG(10,("smb2: failed to create local token: %s\n", 258 nt_errstr(status))); 259 goto fail; 260 } 261 } 262 263 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) || 264 lp_server_signing() == Required) { 265 session->do_signing = true; 266 } 267 268 if (session->session_info->guest) { 269 /* we map anonymous to guest internally */ 270 *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST; 271 *out_session_flags |= SMB2_SESSION_FLAG_IS_NULL; 272 /* force no signing */ 273 session->do_signing = false; 274 } 275 276 data_blob_free(&session->session_info->user_session_key); 277 session->session_info->user_session_key = 278 data_blob_talloc( 279 session->session_info, 280 session_key.data, 281 session_key.length); 282 if (session_key.length > 0) { 283 if (session->session_info->user_session_key.data == NULL) { 284 status = NT_STATUS_NO_MEMORY; 285 goto fail; 286 } 287 } 288 session->session_key = session->session_info->user_session_key; 289 290 session->compat_vuser = talloc_zero(session, user_struct); 291 if (session->compat_vuser == NULL) { 292 status = NT_STATUS_NO_MEMORY; 293 goto fail; 294 } 295 session->compat_vuser->auth_ntlmssp_state = NULL; 296 session->compat_vuser->homes_snum = -1; 297 session->compat_vuser->session_info = session->session_info; 298 session->compat_vuser->session_keystr = NULL; 299 session->compat_vuser->vuid = session->vuid; 300 DLIST_ADD(session->sconn->smb1.sessions.validated_users, session->compat_vuser); 301 302 /* This is a potentially untrusted username */ 303 alpha_strcpy(tmp, user, ". _-$", sizeof(tmp)); 304 session->session_info->sanitized_username = 305 talloc_strdup(session->session_info, tmp); 306 307 if (!session->session_info->guest) { 308 session->compat_vuser->homes_snum = 309 register_homes_share(session->session_info->unix_name); 310 } 311 312 if (!session_claim(session->sconn, session->compat_vuser)) { 313 DEBUG(1, ("smb2: Failed to claim session " 314 "for vuid=%d\n", 315 session->compat_vuser->vuid)); 316 goto fail; 317 } 318 319 session->status = NT_STATUS_OK; 320 321 /* 322 * we attach the session to the request 323 * so that the response can be signed 324 */ 325 smb2req->session = session; 326 if (session->do_signing) { 327 smb2req->do_signing = true; 328 } 329 330 global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32); 331 status = NT_STATUS_OK; 332 333 /* wrap that up in a nice GSS-API wrapping */ 334 ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep, 335 TOK_ID_KRB_AP_REP); 336 337 secblob_out = spnego_gen_auth_response( 338 talloc_tos(), 339 &ap_rep_wrapped, 340 status, 341 mechOID); 342 343 *out_security_buffer = data_blob_talloc(smb2req, 344 secblob_out.data, 345 secblob_out.length); 346 if (secblob_out.data && out_security_buffer->data == NULL) { 347 status = NT_STATUS_NO_MEMORY; 348 goto fail; 349 } 350 351 data_blob_free(&ap_rep); 352 data_blob_free(&ap_rep_wrapped); 353 data_blob_free(&ticket); 354 data_blob_free(&session_key); 355 data_blob_free(&secblob_out); 356 357 *out_session_id = session->vuid; 358 359 return NT_STATUS_OK; 360 361 fail: 362 363 data_blob_free(&ap_rep); 364 data_blob_free(&ap_rep_wrapped); 365 data_blob_free(&ticket); 366 data_blob_free(&session_key); 367 data_blob_free(&secblob_out); 368 369 ap_rep_wrapped = data_blob_null; 370 secblob_out = spnego_gen_auth_response( 371 talloc_tos(), 372 &ap_rep_wrapped, 373 status, 374 mechOID); 375 376 *out_security_buffer = data_blob_talloc(smb2req, 377 secblob_out.data, 378 secblob_out.length); 379 data_blob_free(&secblob_out); 380 return status; 381 } 382 #endif 383 384 static NTSTATUS smbd_smb2_spnego_negotiate(struct smbd_smb2_session *session, 385 struct smbd_smb2_request *smb2req, 386 uint8_t in_security_mode, 387 DATA_BLOB in_security_buffer, 388 uint16_t *out_session_flags, 389 DATA_BLOB *out_security_buffer, 390 uint64_t *out_session_id) 391 { 392 DATA_BLOB secblob_in = data_blob_null; 393 DATA_BLOB chal_out = data_blob_null; 394 char *kerb_mech = NULL; 395 NTSTATUS status; 396 397 /* Ensure we have no old NTLM state around. */ 398 TALLOC_FREE(session->auth_ntlmssp_state); 399 400 status = parse_spnego_mechanisms(talloc_tos(), in_security_buffer, 401 &secblob_in, &kerb_mech); 402 if (!NT_STATUS_IS_OK(status)) { 403 goto out; 404 } 405 406 #ifdef HAVE_KRB5 407 if (kerb_mech && ((lp_security()==SEC_ADS) || 408 USE_KERBEROS_KEYTAB) ) { 409 status = smbd_smb2_session_setup_krb5(session, 410 smb2req, 411 in_security_mode, 412 &secblob_in, 413 kerb_mech, 414 out_session_flags, 415 out_security_buffer, 416 out_session_id); 417 418 goto out; 419 } 420 #endif 421 422 if (kerb_mech) { 423 /* The mechtoken is a krb5 ticket, but 424 * we need to fall back to NTLM. */ 425 426 DEBUG(3,("smb2: Got krb5 ticket in SPNEGO " 427 "but set to downgrade to NTLMSSP\n")); 428 429 status = NT_STATUS_MORE_PROCESSING_REQUIRED; 430 } else { 431 /* Fall back to NTLMSSP. */ 432 status = auth_ntlmssp_start(&session->auth_ntlmssp_state); 433 if (!NT_STATUS_IS_OK(status)) { 434 goto out; 435 } 436 437 status = auth_ntlmssp_update(session->auth_ntlmssp_state, 438 secblob_in, 439 &chal_out); 440 } 441 442 if (!NT_STATUS_IS_OK(status) && 443 !NT_STATUS_EQUAL(status, 444 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 445 goto out; 446 } 447 448 *out_security_buffer = spnego_gen_auth_response(smb2req, 449 &chal_out, 450 status, 451 OID_NTLMSSP); 452 if (out_security_buffer->data == NULL) { 453 status = NT_STATUS_NO_MEMORY; 454 goto out; 455 } 456 *out_session_id = session->vuid; 457 458 out: 459 460 data_blob_free(&secblob_in); 461 data_blob_free(&chal_out); 462 TALLOC_FREE(kerb_mech); 463 if (!NT_STATUS_IS_OK(status) && 464 !NT_STATUS_EQUAL(status, 465 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 466 TALLOC_FREE(session->auth_ntlmssp_state); 467 TALLOC_FREE(session); 468 } 469 return status; 470 } 471 472 static NTSTATUS smbd_smb2_common_ntlmssp_auth_return(struct smbd_smb2_session *session, 473 struct smbd_smb2_request *smb2req, 474 uint8_t in_security_mode, 475 DATA_BLOB in_security_buffer, 476 uint16_t *out_session_flags, 477 uint64_t *out_session_id) 478 { 479 fstring tmp; 480 481 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) || 482 lp_server_signing() == Required) { 483 session->do_signing = true; 484 } 485 486 if (session->session_info->guest) { 487 /* we map anonymous to guest internally */ 488 *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST; 489 *out_session_flags |= SMB2_SESSION_FLAG_IS_NULL; 490 /* force no signing */ 491 session->do_signing = false; 492 } 493 494 session->session_key = session->session_info->user_session_key; 495 496 session->compat_vuser = talloc_zero(session, user_struct); 497 if (session->compat_vuser == NULL) { 498 TALLOC_FREE(session->auth_ntlmssp_state); 499 TALLOC_FREE(session); 500 return NT_STATUS_NO_MEMORY; 501 } 502 session->compat_vuser->auth_ntlmssp_state = session->auth_ntlmssp_state; 503 session->compat_vuser->homes_snum = -1; 504 session->compat_vuser->session_info = session->session_info; 505 session->compat_vuser->session_keystr = NULL; 506 session->compat_vuser->vuid = session->vuid; 507 DLIST_ADD(session->sconn->smb1.sessions.validated_users, session->compat_vuser); 508 509 /* This is a potentially untrusted username */ 510 alpha_strcpy(tmp, 511 auth_ntlmssp_get_username(session->auth_ntlmssp_state), 512 ". _-$", 513 sizeof(tmp)); 514 session->session_info->sanitized_username = talloc_strdup( 515 session->session_info, tmp); 516 517 if (!session->compat_vuser->session_info->guest) { 518 session->compat_vuser->homes_snum = 519 register_homes_share(session->session_info->unix_name); 520 } 521 522 if (!session_claim(session->sconn, session->compat_vuser)) { 523 DEBUG(1, ("smb2: Failed to claim session " 524 "for vuid=%d\n", 525 session->compat_vuser->vuid)); 526 TALLOC_FREE(session->auth_ntlmssp_state); 527 TALLOC_FREE(session); 528 return NT_STATUS_LOGON_FAILURE; 529 } 530 531 532 session->status = NT_STATUS_OK; 533 534 /* 535 * we attach the session to the request 536 * so that the response can be signed 537 */ 538 smb2req->session = session; 539 if (session->do_signing) { 540 smb2req->do_signing = true; 541 } 542 543 global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32); 544 545 *out_session_id = session->vuid; 546 547 return NT_STATUS_OK; 548 } 549 550 static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session, 551 struct smbd_smb2_request *smb2req, 552 uint8_t in_security_mode, 553 DATA_BLOB in_security_buffer, 554 uint16_t *out_session_flags, 555 DATA_BLOB *out_security_buffer, 556 uint64_t *out_session_id) 557 { 558 DATA_BLOB auth = data_blob_null; 559 DATA_BLOB auth_out = data_blob_null; 560 NTSTATUS status; 561 562 if (!spnego_parse_auth(talloc_tos(), in_security_buffer, &auth)) { 563 TALLOC_FREE(session); 564 return NT_STATUS_LOGON_FAILURE; 565 } 566 567 if (auth.data[0] == ASN1_APPLICATION(0)) { 568 /* Might be a second negTokenTarg packet */ 569 DATA_BLOB secblob_in = data_blob_null; 570 char *kerb_mech = NULL; 571 572 status = parse_spnego_mechanisms(talloc_tos(), 573 in_security_buffer, 574 &secblob_in, &kerb_mech); 575 if (!NT_STATUS_IS_OK(status)) { 576 TALLOC_FREE(session); 577 return status; 578 } 579 580 #ifdef HAVE_KRB5 581 if (kerb_mech && ((lp_security()==SEC_ADS) || 582 USE_KERBEROS_KEYTAB) ) { 583 status = smbd_smb2_session_setup_krb5(session, 584 smb2req, 585 in_security_mode, 586 &secblob_in, 587 kerb_mech, 588 out_session_flags, 589 out_security_buffer, 590 out_session_id); 591 592 data_blob_free(&secblob_in); 593 TALLOC_FREE(kerb_mech); 594 if (!NT_STATUS_IS_OK(status)) { 595 TALLOC_FREE(session); 596 } 597 return status; 598 } 599 #endif 600 601 /* Can't blunder into NTLMSSP auth if we have 602 * a krb5 ticket. */ 603 604 if (kerb_mech) { 605 DEBUG(3,("smb2: network " 606 "misconfiguration, client sent us a " 607 "krb5 ticket and kerberos security " 608 "not enabled\n")); 609 TALLOC_FREE(session); 610 data_blob_free(&secblob_in); 611 TALLOC_FREE(kerb_mech); 612 return NT_STATUS_LOGON_FAILURE; 613 } 614 615 data_blob_free(&secblob_in); 616 } 617 618 if (session->auth_ntlmssp_state == NULL) { 619 status = auth_ntlmssp_start(&session->auth_ntlmssp_state); 620 if (!NT_STATUS_IS_OK(status)) { 621 data_blob_free(&auth); 622 TALLOC_FREE(session); 623 return status; 624 } 625 } 626 627 status = auth_ntlmssp_update(session->auth_ntlmssp_state, 628 auth, 629 &auth_out); 630 /* We need to call setup_ntlmssp_session_info() if status==NT_STATUS_OK, 631 or if status is anything except NT_STATUS_MORE_PROCESSING_REQUIRED, 632 as this can trigger map to guest. */ 633 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 634 status = setup_ntlmssp_session_info(session, status); 635 } 636 637 if (!NT_STATUS_IS_OK(status) && 638 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 639 TALLOC_FREE(session->auth_ntlmssp_state); 640 data_blob_free(&auth); 641 TALLOC_FREE(session); 642 return status; 643 } 644 645 data_blob_free(&auth); 646 647 *out_security_buffer = spnego_gen_auth_response(smb2req, 648 &auth_out, status, NULL); 649 650 if (out_security_buffer->data == NULL) { 651 TALLOC_FREE(session->auth_ntlmssp_state); 652 TALLOC_FREE(session); 653 return NT_STATUS_NO_MEMORY; 654 } 655 656 *out_session_id = session->vuid; 657 658 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 659 return NT_STATUS_MORE_PROCESSING_REQUIRED; 660 } 661 662 /* We're done - claim the session. */ 663 return smbd_smb2_common_ntlmssp_auth_return(session, 664 smb2req, 665 in_security_mode, 666 in_security_buffer, 667 out_session_flags, 668 out_session_id); 669 } 670 671 static NTSTATUS smbd_smb2_raw_ntlmssp_auth(struct smbd_smb2_session *session, 672 struct smbd_smb2_request *smb2req, 673 uint8_t in_security_mode, 674 DATA_BLOB in_security_buffer, 675 uint16_t *out_session_flags, 676 DATA_BLOB *out_security_buffer, 677 uint64_t *out_session_id) 678 { 679 NTSTATUS status; 680 DATA_BLOB secblob_out = data_blob_null; 681 682 if (session->auth_ntlmssp_state == NULL) { 683 status = auth_ntlmssp_start(&session->auth_ntlmssp_state); 684 if (!NT_STATUS_IS_OK(status)) { 685 TALLOC_FREE(session); 686 return status; 687 } 688 } 689 690 /* RAW NTLMSSP */ 691 status = auth_ntlmssp_update(session->auth_ntlmssp_state, 692 in_security_buffer, 693 &secblob_out); 694 695 if (NT_STATUS_IS_OK(status) || 696 NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 697 *out_security_buffer = data_blob_talloc(smb2req, 698 secblob_out.data, 699 secblob_out.length); 700 if (secblob_out.data && out_security_buffer->data == NULL) { 701 TALLOC_FREE(session->auth_ntlmssp_state); 702 TALLOC_FREE(session); 703 return NT_STATUS_NO_MEMORY; 704 } 705 } 706 707 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 708 *out_session_id = session->vuid; 709 return status; 710 } 711 712 status = setup_ntlmssp_session_info(session, status); 713 714 if (!NT_STATUS_IS_OK(status)) { 715 TALLOC_FREE(session->auth_ntlmssp_state); 716 TALLOC_FREE(session); 717 return status; 718 } 719 *out_session_id = session->vuid; 720 721 return smbd_smb2_common_ntlmssp_auth_return(session, 722 smb2req, 723 in_security_mode, 724 in_security_buffer, 725 out_session_flags, 726 out_session_id); 727 } 728 729 static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req, 145 730 uint64_t in_session_id, 146 731 uint8_t in_security_mode, … … 151 736 { 152 737 struct smbd_smb2_session *session; 153 NTSTATUS status;154 738 155 739 *out_session_flags = 0; … … 160 744 161 745 /* create a new session */ 162 session = talloc_zero( req->sconn, struct smbd_smb2_session);746 session = talloc_zero(smb2req->sconn, struct smbd_smb2_session); 163 747 if (session == NULL) { 164 748 return NT_STATUS_NO_MEMORY; 165 749 } 166 750 session->status = NT_STATUS_MORE_PROCESSING_REQUIRED; 167 id = idr_get_new_random( req->sconn->smb2.sessions.idtree,751 id = idr_get_new_random(smb2req->sconn->smb2.sessions.idtree, 168 752 session, 169 req->sconn->smb2.sessions.limit);753 smb2req->sconn->smb2.sessions.limit); 170 754 if (id == -1) { 171 755 return NT_STATUS_INSUFFICIENT_RESOURCES; … … 180 764 session->tcons.list = NULL; 181 765 182 DLIST_ADD_END( req->sconn->smb2.sessions.list, session,766 DLIST_ADD_END(smb2req->sconn->smb2.sessions.list, session, 183 767 struct smbd_smb2_session *); 184 session->sconn = req->sconn;768 session->sconn = smb2req->sconn; 185 769 talloc_set_destructor(session, smbd_smb2_session_destructor); 186 770 } else { … … 188 772 189 773 /* lookup an existing session */ 190 p = idr_find( req->sconn->smb2.sessions.idtree, in_session_id);774 p = idr_find(smb2req->sconn->smb2.sessions.idtree, in_session_id); 191 775 if (p == NULL) { 192 776 return NT_STATUS_USER_SESSION_DELETED; … … 199 783 } 200 784 201 if (session->auth_ntlmssp_state == NULL) {202 status = auth_ntlmssp_start(&session->auth_ntlmssp_state);203 if (!NT_STATUS_IS_OK(status)) {204 TALLOC_FREE(session);205 return status;206 }207 }208 209 785 if (in_security_buffer.data[0] == ASN1_APPLICATION(0)) { 210 DATA_BLOB secblob_in; 211 DATA_BLOB chal_out; 212 char *kerb_mech = NULL; 213 214 status = parse_spnego_mechanisms(in_security_buffer, 215 &secblob_in, &kerb_mech); 216 if (!NT_STATUS_IS_OK(status)) { 217 TALLOC_FREE(session); 218 return nt_status_squash(status); 219 } 220 221 /* For now, just SPNEGO NTLMSSP - krb5 goes here later.. */ 222 status = auth_ntlmssp_update(session->auth_ntlmssp_state, 223 secblob_in, 224 &chal_out); 225 226 if (!NT_STATUS_IS_OK(status) && 227 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 228 auth_ntlmssp_end(&session->auth_ntlmssp_state); 229 TALLOC_FREE(session); 230 return nt_status_squash(status); 231 } 232 233 *out_security_buffer = spnego_gen_auth_response(&chal_out, 234 status, OID_NTLMSSP); 235 236 *out_session_id = session->vuid; 237 return status; 786 return smbd_smb2_spnego_negotiate(session, 787 smb2req, 788 in_security_mode, 789 in_security_buffer, 790 out_session_flags, 791 out_security_buffer, 792 out_session_id); 238 793 } else if (in_security_buffer.data[0] == ASN1_CONTEXT(1)) { 239 DATA_BLOB auth = data_blob_null; 240 DATA_BLOB auth_out = data_blob_null; 241 242 /* its an auth packet */ 243 if (!spnego_parse_auth(in_security_buffer, &auth)) { 244 TALLOC_FREE(session); 245 return NT_STATUS_LOGON_FAILURE; 246 } 247 /* For now, just SPNEGO NTLMSSP - krb5 goes here later.. */ 248 status = auth_ntlmssp_update(session->auth_ntlmssp_state, 249 auth, 250 &auth_out); 251 if (!NT_STATUS_IS_OK(status)) { 252 auth_ntlmssp_end(&session->auth_ntlmssp_state); 253 TALLOC_FREE(session); 254 return nt_status_squash(status); 255 } 256 257 *out_security_buffer = spnego_gen_auth_response(&auth_out, 258 status, NULL); 259 260 *out_session_id = session->vuid; 794 return smbd_smb2_spnego_auth(session, 795 smb2req, 796 in_security_mode, 797 in_security_buffer, 798 out_session_flags, 799 out_security_buffer, 800 out_session_id); 261 801 } else if (strncmp((char *)(in_security_buffer.data), "NTLMSSP", 7) == 0) { 262 263 /* RAW NTLMSSP */ 264 status = auth_ntlmssp_update(session->auth_ntlmssp_state, 265 in_security_buffer, 266 out_security_buffer); 267 268 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 269 *out_session_id = session->vuid; 270 return status; 271 } 272 if (!NT_STATUS_IS_OK(status)) { 273 auth_ntlmssp_end(&session->auth_ntlmssp_state); 274 TALLOC_FREE(session); 275 return nt_status_squash(status); 276 } 277 *out_session_id = session->vuid; 278 } 279 280 /* TODO: setup session key for signing */ 281 282 if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) || 283 lp_server_signing() == Required) { 284 session->do_signing = true; 285 } 286 287 if (session->auth_ntlmssp_state->server_info->guest) { 288 /* we map anonymous to guest internally */ 289 *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST; 290 *out_session_flags |= SMB2_SESSION_FLAG_IS_NULL; 291 /* force no signing */ 292 session->do_signing = false; 293 } 294 295 session->server_info = session->auth_ntlmssp_state->server_info; 296 data_blob_free(&session->server_info->user_session_key); 297 session->server_info->user_session_key = 298 data_blob_talloc( 299 session->server_info, 300 session->auth_ntlmssp_state->ntlmssp_state->session_key.data, 301 session->auth_ntlmssp_state->ntlmssp_state->session_key.length); 302 if (session->auth_ntlmssp_state->ntlmssp_state->session_key.length > 0) { 303 if (session->server_info->user_session_key.data == NULL) { 304 TALLOC_FREE(session); 305 return NT_STATUS_NO_MEMORY; 306 } 307 } 308 session->session_key = session->server_info->user_session_key; 309 310 session->compat_vuser = talloc_zero(session, user_struct); 311 if (session->compat_vuser == NULL) { 312 TALLOC_FREE(session); 313 return NT_STATUS_NO_MEMORY; 314 } 315 session->compat_vuser->auth_ntlmssp_state = session->auth_ntlmssp_state; 316 session->compat_vuser->homes_snum = -1; 317 session->compat_vuser->server_info = session->server_info; 318 session->compat_vuser->session_keystr = NULL; 319 session->compat_vuser->vuid = session->vuid; 320 DLIST_ADD(session->sconn->smb1.sessions.validated_users, session->compat_vuser); 321 322 session->status = NT_STATUS_OK; 323 324 /* 325 * we attach the session to the request 326 * so that the response can be signed 327 */ 328 req->session = session; 329 if (session->do_signing) { 330 req->do_signing = true; 331 } 332 333 *out_session_id = session->vuid; 334 return status; 802 return smbd_smb2_raw_ntlmssp_auth(session, 803 smb2req, 804 in_security_mode, 805 in_security_buffer, 806 out_session_flags, 807 out_security_buffer, 808 out_session_id); 809 } 810 811 /* Unknown packet type. */ 812 DEBUG(1,("Unknown packet type %u in smb2 sessionsetup\n", 813 (unsigned int)in_security_buffer.data[0] )); 814 TALLOC_FREE(session->auth_ntlmssp_state); 815 TALLOC_FREE(session); 816 return NT_STATUS_LOGON_FAILURE; 335 817 } 336 818 … … 338 820 { 339 821 const uint8_t *inhdr; 822 const uint8_t *outhdr; 340 823 int i = req->current_idx; 341 824 uint64_t in_session_id; 342 825 void *p; 343 826 struct smbd_smb2_session *session; 827 bool chained_fixup = false; 344 828 345 829 inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; 346 830 347 831 in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID); 832 833 if (in_session_id == (0xFFFFFFFFFFFFFFFFLL)) { 834 if (req->async) { 835 /* 836 * async request - fill in session_id from 837 * already setup request out.vector[].iov_base. 838 */ 839 outhdr = (const uint8_t *)req->out.vector[i].iov_base; 840 in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID); 841 } else if (i > 2) { 842 /* 843 * Chained request - fill in session_id from 844 * the previous request out.vector[].iov_base. 845 */ 846 outhdr = (const uint8_t *)req->out.vector[i-3].iov_base; 847 in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID); 848 chained_fixup = true; 849 } 850 } 348 851 349 852 /* lookup an existing session */ … … 358 861 } 359 862 360 set_current_user_info(session->se rver_info->sanitized_username,361 session->se rver_info->unix_name,362 pdb_get_domain(session->server_info->sam_account));863 set_current_user_info(session->session_info->sanitized_username, 864 session->session_info->unix_name, 865 session->session_info->info3->base.domain.string); 363 866 364 867 req->session = session; 868 869 if (chained_fixup) { 870 /* Fix up our own outhdr. */ 871 outhdr = (const uint8_t *)req->out.vector[i].iov_base; 872 SBVAL(outhdr, SMB2_HDR_SESSION_ID, in_session_id); 873 } 365 874 return NT_STATUS_OK; 366 875 }
Note:
See TracChangeset
for help on using the changeset viewer.