Changeset 988 for vendor/current/source3/libsmb/clifsinfo.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/clifsinfo.c
r746 r988 4 4 Copyright (C) Stefan (metze) Metzmacher 2003 5 5 Copyright (C) Jeremy Allison 2007 6 Copyright (C) Andrew Bartlett 2011 6 7 7 8 This program is free software; you can redistribute it and/or modify … … 21 22 #include "includes.h" 22 23 #include "libsmb/libsmb.h" 23 #include "../libcli/auth/spnego.h"24 #include "../libcli/auth/ntlmssp.h"25 24 #include "../lib/util/tevent_ntstatus.h" 26 25 #include "async_smb.h" 27 #include " smb_crypt.h"26 #include "../libcli/smb/smb_seal.h" 28 27 #include "trans2.h" 28 #include "auth_generic.h" 29 #include "auth/gensec/gensec.h" 30 #include "../libcli/smb/smbXcli_base.h" 31 #include "auth/credentials/credentials.h" 29 32 30 33 /**************************************************************************** … … 116 119 } 117 120 118 NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor,119 uint16 *pminor, uint32*pcaplow,120 uint32 *pcaphigh)121 NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16_t *pmajor, 122 uint16_t *pminor, uint32_t *pcaplow, 123 uint32_t *pcaphigh) 121 124 { 122 125 TALLOC_CTX *frame = talloc_stackframe(); 123 struct event_context *ev;126 struct tevent_context *ev; 124 127 struct tevent_req *req; 125 128 NTSTATUS status = NT_STATUS_OK; 126 129 127 if ( cli_has_async_calls(cli)) {130 if (smbXcli_conn_has_async_calls(cli->conn)) { 128 131 /* 129 132 * Can't use sync call while an async call is in flight … … 133 136 } 134 137 135 ev = event_context_init(frame);138 ev = samba_tevent_context_init(frame); 136 139 if (ev == NULL) { 137 140 status = NT_STATUS_NO_MEMORY; … … 145 148 } 146 149 147 if (!tevent_req_poll(req, ev)) { 148 status = map_nt_error_from_unix(errno); 150 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 149 151 goto fail; 150 152 } … … 231 233 232 234 NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli, 233 uint16 major, uint16minor,234 uint32 caplow, uint32caphigh)235 uint16_t major, uint16_t minor, 236 uint32_t caplow, uint32_t caphigh) 235 237 { 236 238 struct tevent_context *ev; … … 238 240 NTSTATUS status = NT_STATUS_NO_MEMORY; 239 241 240 if ( cli_has_async_calls(cli)) {242 if (smbXcli_conn_has_async_calls(cli->conn)) { 241 243 return NT_STATUS_INVALID_PARAMETER; 242 244 } 243 ev = tevent_context_init(talloc_tos());245 ev = samba_tevent_context_init(talloc_tos()); 244 246 if (ev == NULL) { 245 247 goto fail; … … 335 337 NTSTATUS status = NT_STATUS_NO_MEMORY; 336 338 337 if ( cli_has_async_calls(cli)) {339 if (smbXcli_conn_has_async_calls(cli->conn)) { 338 340 return NT_STATUS_INVALID_PARAMETER; 339 341 } 340 ev = tevent_context_init(talloc_tos());342 ev = samba_tevent_context_init(talloc_tos()); 341 343 if (ev == NULL) { 342 344 goto fail; … … 355 357 } 356 358 357 NTSTATUS cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, 358 uint32 *pserial_number, time_t *pdate) 359 { 360 NTSTATUS status; 361 uint16 setup[1]; 359 NTSTATUS cli_get_fs_volume_info(struct cli_state *cli, 360 TALLOC_CTX *mem_ctx, 361 char **_volume_name, 362 uint32_t *pserial_number, 363 time_t *pdate) 364 { 365 NTSTATUS status; 366 uint16_t recv_flags2; 367 uint16_t setup[1]; 362 368 uint8_t param[2]; 363 369 uint8_t *rdata; 364 370 uint32_t rdata_count; 365 371 unsigned int nlen; 372 char *volume_name = NULL; 366 373 367 374 SSVAL(setup, 0, TRANSACT2_QFSINFO); … … 373 380 param, 2, 0, 374 381 NULL, 0, 560, 375 NULL,382 &recv_flags2, 376 383 NULL, 0, NULL, 377 384 NULL, 0, NULL, 378 &rdata, 1 0, &rdata_count);385 &rdata, 18, &rdata_count); 379 386 if (!NT_STATUS_IS_OK(status)) { 380 387 return status; … … 390 397 } 391 398 nlen = IVAL(rdata,12); 392 clistr_pull(cli->inbuf, volume_name, rdata + 18, sizeof(fstring), 393 nlen, STR_UNICODE); 399 if (nlen > (rdata_count - 18)) { 400 TALLOC_FREE(rdata); 401 return NT_STATUS_INVALID_NETWORK_RESPONSE; 402 } 403 404 clistr_pull_talloc(mem_ctx, 405 (const char *)rdata, 406 recv_flags2, 407 &volume_name, 408 rdata + 18, 409 nlen, STR_UNICODE); 410 if (volume_name == NULL) { 411 status = map_nt_error_from_unix(errno); 412 TALLOC_FREE(rdata); 413 return status; 414 } 394 415 395 416 /* todo: but not yet needed … … 397 418 */ 398 419 420 *_volume_name = volume_name; 399 421 TALLOC_FREE(rdata); 400 422 return NT_STATUS_OK; … … 408 430 uint64_t *bytes_per_sector) 409 431 { 410 uint16 setup[1];432 uint16_t setup[1]; 411 433 uint8_t param[2]; 412 434 uint8_t *rdata = NULL; … … 452 474 453 475 NTSTATUS cli_get_posix_fs_info(struct cli_state *cli, 454 uint32 *optimal_transfer_size,455 uint32 *block_size,476 uint32_t *optimal_transfer_size, 477 uint32_t *block_size, 456 478 uint64_t *total_blocks, 457 479 uint64_t *blocks_available, … … 461 483 uint64_t *fs_identifier) 462 484 { 463 uint16 setup[1];485 uint16_t setup[1]; 464 486 uint8_t param[2]; 465 487 uint8_t *rdata = NULL; … … 549 571 550 572 /****************************************************************************** 551 Make a client state struct.552 ******************************************************************************/553 554 static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type smb_enc_type)555 {556 struct smb_trans_enc_state *es = NULL;557 es = SMB_MALLOC_P(struct smb_trans_enc_state);558 if (!es) {559 return NULL;560 }561 ZERO_STRUCTP(es);562 es->smb_enc_type = smb_enc_type;563 564 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)565 if (smb_enc_type == SMB_TRANS_ENC_GSS) {566 es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss);567 if (!es->s.gss_state) {568 SAFE_FREE(es);569 return NULL;570 }571 ZERO_STRUCTP(es->s.gss_state);572 }573 #endif574 return es;575 }576 577 /******************************************************************************578 573 Start a raw ntlmssp encryption. 579 574 ******************************************************************************/ … … 588 583 DATA_BLOB param_out = data_blob_null; 589 584 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 590 struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_NTLM);591 585 struct auth_generic_state *auth_generic_state; 586 struct smb_trans_enc_state *es = talloc_zero(NULL, struct smb_trans_enc_state); 592 587 if (!es) { 593 588 return NT_STATUS_NO_MEMORY; 594 589 } 595 status = ntlmssp_client_start(NULL, 596 global_myname(), 597 lp_workgroup(), 598 lp_client_ntlmv2_auth(), 599 &es->s.ntlmssp_state); 600 if (!NT_STATUS_IS_OK(status)) { 601 goto fail; 602 } 603 604 ntlmssp_want_feature(es->s.ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); 605 es->s.ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL); 606 607 if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->s.ntlmssp_state, user))) { 608 goto fail; 609 } 610 if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->s.ntlmssp_state, domain))) { 611 goto fail; 612 } 613 if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->s.ntlmssp_state, pass))) { 590 status = auth_generic_client_prepare(es, 591 &auth_generic_state); 592 if (!NT_STATUS_IS_OK(status)) { 593 goto fail; 594 } 595 596 gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY); 597 gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL); 598 599 if (!NT_STATUS_IS_OK(status = auth_generic_set_username(auth_generic_state, user))) { 600 goto fail; 601 } 602 if (!NT_STATUS_IS_OK(status = auth_generic_set_domain(auth_generic_state, domain))) { 603 goto fail; 604 } 605 if (!NT_STATUS_IS_OK(status = auth_generic_set_password(auth_generic_state, pass))) { 606 goto fail; 607 } 608 609 if (!NT_STATUS_IS_OK(status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP))) { 614 610 goto fail; 615 611 } 616 612 617 613 do { 618 status = ntlmssp_update(es->s.ntlmssp_state, blob_in, &blob_out); 614 status = gensec_update(auth_generic_state->gensec_security, auth_generic_state, 615 blob_in, &blob_out); 619 616 data_blob_free(&blob_in); 620 617 data_blob_free(¶m_out); … … 640 637 641 638 if (NT_STATUS_IS_OK(status)) { 639 es->enc_on = true; 642 640 /* Replace the old state, if any. */ 643 if (cli->trans_enc_state) { 644 common_free_encryption_state(&cli->trans_enc_state); 645 } 646 cli->trans_enc_state = es; 647 cli->trans_enc_state->enc_on = True; 641 /* We only need the gensec_security part from here. 642 * es is a malloc()ed pointer, so we cannot make 643 * gensec_security a talloc child */ 644 es->gensec_security = talloc_move(NULL, 645 &auth_generic_state->gensec_security); 646 smb1cli_conn_set_encryption(cli->conn, es); 648 647 es = NULL; 649 648 } 650 649 651 650 fail: 652 653 common_free_encryption_state(&es); 654 return status; 655 } 656 657 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) 658 659 #ifndef SMB_GSS_REQUIRED_FLAGS 660 #define SMB_GSS_REQUIRED_FLAGS (GSS_C_CONF_FLAG|GSS_C_INTEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG) 661 #endif 662 663 /****************************************************************************** 664 Get client gss blob to send to a server. 665 ******************************************************************************/ 666 667 static NTSTATUS make_cli_gss_blob(TALLOC_CTX *ctx, 668 struct smb_trans_enc_state *es, 669 const char *service, 670 const char *host, 671 NTSTATUS status_in, 672 DATA_BLOB spnego_blob_in, 673 DATA_BLOB *p_blob_out) 674 { 675 const char *krb_mechs[] = {OID_KERBEROS5, NULL}; 676 OM_uint32 ret; 677 OM_uint32 min; 678 gss_name_t srv_name; 679 gss_buffer_desc input_name; 680 gss_buffer_desc *p_tok_in; 681 gss_buffer_desc tok_out, tok_in; 682 DATA_BLOB blob_out = data_blob_null; 683 DATA_BLOB blob_in = data_blob_null; 684 char *host_princ_s = NULL; 685 OM_uint32 ret_flags = 0; 686 NTSTATUS status = NT_STATUS_OK; 687 688 gss_OID_desc nt_hostbased_service = 689 {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")}; 690 691 memset(&tok_out, '\0', sizeof(tok_out)); 692 693 /* Get a ticket for the service@host */ 694 if (asprintf(&host_princ_s, "%s@%s", service, host) == -1) { 695 return NT_STATUS_NO_MEMORY; 696 } 697 698 input_name.value = host_princ_s; 699 input_name.length = strlen(host_princ_s) + 1; 700 701 ret = gss_import_name(&min, 702 &input_name, 703 &nt_hostbased_service, 704 &srv_name); 705 706 if (ret != GSS_S_COMPLETE) { 707 SAFE_FREE(host_princ_s); 708 return map_nt_error_from_gss(ret, min); 709 } 710 711 if (spnego_blob_in.length == 0) { 712 p_tok_in = GSS_C_NO_BUFFER; 713 } else { 714 /* Remove the SPNEGO wrapper */ 715 if (!spnego_parse_auth_response(ctx, spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) { 716 status = NT_STATUS_UNSUCCESSFUL; 717 goto fail; 718 } 719 tok_in.value = blob_in.data; 720 tok_in.length = blob_in.length; 721 p_tok_in = &tok_in; 722 } 723 724 ret = gss_init_sec_context(&min, 725 GSS_C_NO_CREDENTIAL, /* Use our default cred. */ 726 &es->s.gss_state->gss_ctx, 727 srv_name, 728 GSS_C_NO_OID, /* default OID. */ 729 GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG, 730 GSS_C_INDEFINITE, /* requested ticket lifetime. */ 731 NULL, /* no channel bindings */ 732 p_tok_in, 733 NULL, /* ignore mech type */ 734 &tok_out, 735 &ret_flags, 736 NULL); /* ignore time_rec */ 737 738 status = map_nt_error_from_gss(ret, min); 739 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { 740 ADS_STATUS adss = ADS_ERROR_GSS(ret, min); 741 DEBUG(10,("make_cli_gss_blob: gss_init_sec_context failed with %s\n", 742 ads_errstr(adss))); 743 goto fail; 744 } 745 746 if ((ret_flags & SMB_GSS_REQUIRED_FLAGS) != SMB_GSS_REQUIRED_FLAGS) { 747 status = NT_STATUS_ACCESS_DENIED; 748 } 749 750 blob_out = data_blob_talloc(ctx, tok_out.value, tok_out.length); 751 752 /* Wrap in an SPNEGO wrapper */ 753 *p_blob_out = spnego_gen_negTokenInit(ctx, krb_mechs, &blob_out, NULL); 754 755 fail: 756 757 data_blob_free(&blob_out); 758 data_blob_free(&blob_in); 759 SAFE_FREE(host_princ_s); 760 gss_release_name(&min, &srv_name); 761 if (tok_out.value) { 762 gss_release_buffer(&min, &tok_out); 763 } 651 TALLOC_FREE(es); 764 652 return status; 765 653 } … … 775 663 DATA_BLOB param_out = data_blob_null; 776 664 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 777 fstring fqdn; 778 const char *servicename; 779 struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_GSS); 665 struct auth_generic_state *auth_generic_state; 666 struct smb_trans_enc_state *es = talloc_zero(NULL, struct smb_trans_enc_state); 780 667 781 668 if (!es) { … … 783 670 } 784 671 785 name_to_fqdn(fqdn, cli->desthost); 786 strlower_m(fqdn); 787 788 servicename = "cifs"; 789 status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); 790 if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { 791 servicename = "host"; 792 status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); 793 if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { 794 goto fail; 795 } 796 } 672 status = auth_generic_client_prepare(es, 673 &auth_generic_state); 674 if (!NT_STATUS_IS_OK(status)) { 675 goto fail; 676 } 677 678 gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY); 679 gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL); 680 681 cli_credentials_set_kerberos_state(auth_generic_state->credentials, 682 CRED_MUST_USE_KERBEROS); 683 684 status = gensec_set_target_service(auth_generic_state->gensec_security, "cifs"); 685 if (!NT_STATUS_IS_OK(status)) { 686 goto fail; 687 } 688 689 status = gensec_set_target_hostname(auth_generic_state->gensec_security, 690 smbXcli_conn_remote_name(cli->conn)); 691 if (!NT_STATUS_IS_OK(status)) { 692 goto fail; 693 } 694 695 if (!NT_STATUS_IS_OK(status = auth_generic_client_start(auth_generic_state, GENSEC_OID_SPNEGO))) { 696 goto fail; 697 } 698 699 status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), 700 blob_recv, &blob_send); 797 701 798 702 do { … … 803 707 } 804 708 data_blob_free(&blob_send); 805 status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, status, blob_recv, &blob_send); 709 status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), 710 blob_recv, &blob_send); 806 711 } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); 807 712 data_blob_free(&blob_recv); 808 713 809 714 if (NT_STATUS_IS_OK(status)) { 715 if (!gensec_have_feature(auth_generic_state->gensec_security, 716 GENSEC_FEATURE_SIGN) || 717 !gensec_have_feature(auth_generic_state->gensec_security, 718 GENSEC_FEATURE_SEAL)) { 719 status = NT_STATUS_ACCESS_DENIED; 720 } 721 } 722 723 if (NT_STATUS_IS_OK(status)) { 724 es->enc_on = true; 810 725 /* Replace the old state, if any. */ 811 if (cli->trans_enc_state) { 812 common_free_encryption_state(&cli->trans_enc_state); 813 } 814 cli->trans_enc_state = es; 815 cli->trans_enc_state->enc_on = True; 726 /* We only need the gensec_security part from here. 727 * es is a malloc()ed pointer, so we cannot make 728 * gensec_security a talloc child */ 729 es->gensec_security = talloc_move(es, 730 &auth_generic_state->gensec_security); 731 smb1cli_conn_set_encryption(cli->conn, es); 816 732 es = NULL; 817 733 } 818 819 fail: 820 821 common_free_encryption_state(&es); 734 fail: 735 TALLOC_FREE(es); 822 736 return status; 823 737 } 824 #else825 NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli)826 {827 return NT_STATUS_NOT_SUPPORTED;828 }829 #endif830 738 831 739 /******************************************************************** … … 838 746 const char *domain) 839 747 { 840 uint16 major, minor;841 uint32 caplow, caphigh;748 uint16_t major, minor; 749 uint32_t caplow, caphigh; 842 750 NTSTATUS status; 843 751
Note:
See TracChangeset
for help on using the changeset viewer.