Changeset 590 for trunk/server/source3/libsmb/clikrb5.c
- Timestamp:
- Jul 1, 2011, 8:40:10 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server/source3/libsmb/clikrb5.c
r414 r590 29 29 #define GSSAPI_CHECKSUM 0x8003 /* Checksum type value for Kerberos */ 30 30 #define GSSAPI_BNDLENGTH 16 /* Bind Length (rfc-1964 pg.3) */ 31 #define GSSAPI_CHECKSUM_SIZE (12+GSSAPI_BNDLENGTH) 32 33 #if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) 34 static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context, 35 krb5_auth_context *auth_context, 36 krb5_creds *credsp, 37 krb5_ccache ccache, 38 krb5_data *authenticator); 31 #define GSSAPI_CHECKSUM_SIZE (4+GSSAPI_BNDLENGTH+4) /* Length of bind length, 32 bind field, flags field. */ 33 34 /* MIT krb5 1.7beta3 (in Ubuntu Karmic) is missing the prototype, 35 but still has the symbol */ 36 #if !HAVE_DECL_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE 37 krb5_error_code krb5_auth_con_set_req_cksumtype( 38 krb5_context context, 39 krb5_auth_context auth_context, 40 krb5_cksumtype cksumtype); 39 41 #endif 40 42 … … 646 648 } 647 649 650 /* Allocate and setup the auth context into the state we need. */ 651 652 static krb5_error_code setup_auth_context(krb5_context context, 653 krb5_auth_context *auth_context) 654 { 655 krb5_error_code retval; 656 657 retval = krb5_auth_con_init(context, auth_context ); 658 if (retval) { 659 DEBUG(1,("krb5_auth_con_init failed (%s)\n", 660 error_message(retval))); 661 return retval; 662 } 663 664 /* Ensure this is an addressless ticket. */ 665 retval = krb5_auth_con_setaddrs(context, *auth_context, NULL, NULL); 666 if (retval) { 667 DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", 668 error_message(retval))); 669 } 670 671 return retval; 672 } 673 674 static krb5_error_code create_gss_checksum(krb5_data *in_data, /* [inout] */ 675 uint32_t gss_flags) 676 { 677 unsigned int orig_length = in_data->length; 678 unsigned int base_cksum_size = GSSAPI_CHECKSUM_SIZE; 679 char *gss_cksum = NULL; 680 681 if (orig_length) { 682 /* Extra length field for delgated ticket. */ 683 base_cksum_size += 4; 684 } 685 686 if ((unsigned int)base_cksum_size + orig_length < 687 (unsigned int)base_cksum_size) { 688 return EINVAL; 689 } 690 691 gss_cksum = (char *)SMB_MALLOC(base_cksum_size + orig_length); 692 if (gss_cksum == NULL) { 693 return ENOMEM; 694 } 695 696 memset(gss_cksum, '\0', base_cksum_size + orig_length); 697 SIVAL(gss_cksum, 0, GSSAPI_BNDLENGTH); 698 699 /* Precalculated MD5sum of NULL channel bindings (20 bytes) */ 700 /* Channel bindings are: (all ints encoded as little endian) 701 702 [4 bytes] initiator_addrtype (255 for null bindings) 703 [4 bytes] initiator_address length 704 [n bytes] .. initiator_address data - not present 705 in null bindings. 706 [4 bytes] acceptor_addrtype (255 for null bindings) 707 [4 bytes] acceptor_address length 708 [n bytes] .. acceptor_address data - not present 709 in null bindings. 710 [4 bytes] application_data length 711 [n bytes] .. application_ data - not present 712 in null bindings. 713 MD5 of this is ""\x14\x8f\x0c\xf7\xb1u\xdey*J\x9a%\xdfV\xc5\x18" 714 */ 715 716 memcpy(&gss_cksum[4], 717 "\x14\x8f\x0c\xf7\xb1u\xdey*J\x9a%\xdfV\xc5\x18", 718 GSSAPI_BNDLENGTH); 719 720 SIVAL(gss_cksum, 20, gss_flags); 721 722 if (orig_length) { 723 SSVAL(gss_cksum, 24, 1); /* The Delegation Option identifier */ 724 SSVAL(gss_cksum, 26, orig_length); 725 /* Copy the kerberos KRB_CRED data */ 726 memcpy(gss_cksum + 28, in_data->data, orig_length); 727 free(in_data->data); 728 in_data->data = NULL; 729 in_data->length = 0; 730 } 731 in_data->data = gss_cksum; 732 in_data->length = base_cksum_size + orig_length; 733 return 0; 734 } 735 648 736 /* 649 737 we can't use krb5_mk_req because w2k wants the service to be in a particular format … … 666 754 bool creds_ready = False; 667 755 int i = 0, maxtries = 3; 668 756 uint32_t gss_flags = 0; 757 669 758 ZERO_STRUCT(in_data); 670 759 … … 736 825 } 737 826 738 #if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) 827 /* Allocate the auth_context. */ 828 retval = setup_auth_context(context, auth_context); 829 if (retval) { 830 DEBUG(1,("setup_auth_context failed (%s)\n", 831 error_message(retval))); 832 goto cleanup_creds; 833 } 834 835 #if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) 739 836 if( credsp->ticket_flags & TKT_FLG_OK_AS_DELEGATE ) { 740 837 /* Fetch a forwarded TGT from the KDC so that we can hand off a 2nd ticket … … 743 840 DEBUG( 3, ("ads_krb5_mk_req: server marked as OK to delegate to, building forwardable TGT\n") ); 744 841 745 if( *auth_context == NULL ) { 746 /* Allocate if it has not yet been allocated. */ 747 retval = krb5_auth_con_init( context, auth_context ); 748 if (retval) { 749 DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_init failed (%s)\n", 750 error_message(retval))); 751 goto cleanup_creds; 752 } 753 } 754 755 retval = krb5_auth_con_setuseruserkey( context, *auth_context, &credsp->keyblock ); 842 retval = krb5_auth_con_setuseruserkey(context, 843 *auth_context, 844 &credsp->keyblock ); 756 845 if (retval) { 757 DEBUG(1,(" ads_krb5_mk_req:krb5_auth_con_setuseruserkey failed (%s)\n",846 DEBUG(1,("krb5_auth_con_setuseruserkey failed (%s)\n", 758 847 error_message(retval))); 759 848 goto cleanup_creds; … … 761 850 762 851 /* Must use a subkey for forwarded tickets. */ 763 retval = krb5_auth_con_setflags( context, *auth_context, KRB5_AUTH_CONTEXT_USE_SUBKEY); 852 retval = krb5_auth_con_setflags(context, 853 *auth_context, 854 KRB5_AUTH_CONTEXT_USE_SUBKEY); 764 855 if (retval) { 765 DEBUG(1,(" ads_krb5_mk_req:krb5_auth_con_setflags failed (%s)\n",856 DEBUG(1,("krb5_auth_con_setflags failed (%s)\n", 766 857 error_message(retval))); 767 858 goto cleanup_creds; 768 859 } 769 860 770 retval = ads_krb5_get_fwd_ticket( context, 771 auth_context, 772 credsp, 773 ccache, 774 &in_data ); 861 retval = krb5_fwd_tgt_creds(context,/* Krb5 context [in] */ 862 *auth_context, /* Authentication context [in] */ 863 CONST_DISCARD(char *, KRB5_TGS_NAME), /* Ticket service name ("krbtgt") [in] */ 864 credsp->client, /* Client principal for the tgt [in] */ 865 credsp->server, /* Server principal for the tgt [in] */ 866 ccache, /* Credential cache to use for storage [in] */ 867 1, /* Turn on for "Forwardable ticket" [in] */ 868 &in_data ); /* Resulting response [out] */ 869 775 870 if (retval) { 776 DEBUG( 3, (" ads_krb5_get_fwd_ticketfailed (%s)\n",871 DEBUG( 3, ("krb5_fwd_tgt_creds failed (%s)\n", 777 872 error_message( retval ) ) ); 778 873 … … 789 884 krb5_auth_con_free(context, *auth_context); 790 885 *auth_context = NULL; 791 } 886 retval = setup_auth_context(context, auth_context); 887 if (retval) { 888 DEBUG(1,("setup_auth_context failed (%s)\n", 889 error_message(retval))); 890 goto cleanup_creds; 891 } 892 } else { 893 /* We got a delegated ticket. */ 894 gss_flags |= GSS_C_DELEG_FLAG; 895 } 896 } 897 #endif 898 899 /* Frees and reallocates in_data into a GSS checksum blob. */ 900 retval = create_gss_checksum(&in_data, gss_flags); 901 if (retval) { 902 goto cleanup_data; 903 } 904 905 #if defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) 906 /* We always want GSS-checksum types. */ 907 retval = krb5_auth_con_set_req_cksumtype(context, *auth_context, GSSAPI_CHECKSUM ); 908 if (retval) { 909 DEBUG(1,("krb5_auth_con_set_req_cksumtype failed (%s)\n", 910 error_message(retval))); 911 goto cleanup_data; 792 912 } 793 913 #endif … … 800 920 } 801 921 922 cleanup_data: 802 923 if (in_data.data) { 803 924 free( in_data.data ); … … 1846 1967 return ret; 1847 1968 } 1848 1849 #if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY)1850 /**************************************************************1851 Routine: ads_krb5_get_fwd_ticket1852 Description:1853 When a service ticket is flagged as trusted1854 for delegation we should provide a forwardable1855 ticket so that the remote host can act on our1856 behalf. This is done by taking the 2nd forwardable1857 TGT and storing it in the GSS-API authenticator1858 "checksum". This routine will populate1859 the krb5_data authenticator with this TGT.1860 Parameters:1861 krb5_context context: The kerberos context for this authentication.1862 krb5_auth_context: The authentication context.1863 krb5_creds *credsp: The ticket credentials (AS-REP).1864 krb5_ccache ccache: The credentials cache.1865 krb5_data &authenticator: The checksum field that will store the TGT, and1866 authenticator.data must be freed by the caller.1867 1868 Returns:1869 krb5_error_code: 0 if no errors, otherwise set.1870 **************************************************************/1871 1872 static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context,1873 krb5_auth_context *auth_context,1874 krb5_creds *credsp,1875 krb5_ccache ccache,1876 krb5_data *authenticator)1877 {1878 krb5_data fwdData;1879 krb5_error_code retval = 0;1880 char *pChksum = NULL;1881 char *p = NULL;1882 1883 /* MIT krb5 1.7beta3 (in Ubuntu Karmic) is missing the prototype,1884 but still has the symbol */1885 #if !HAVE_DECL_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE1886 krb5_error_code krb5_auth_con_set_req_cksumtype(1887 krb5_context context,1888 krb5_auth_context auth_context,1889 krb5_cksumtype cksumtype);1890 #endif1891 1892 ZERO_STRUCT(fwdData);1893 ZERO_STRUCTP(authenticator);1894 1895 retval = krb5_fwd_tgt_creds(context,/* Krb5 context [in] */1896 *auth_context, /* Authentication context [in] */1897 CONST_DISCARD(char *, KRB5_TGS_NAME), /* Ticket service name ("krbtgt") [in] */1898 credsp->client, /* Client principal for the tgt [in] */1899 credsp->server, /* Server principal for the tgt [in] */1900 ccache, /* Credential cache to use for storage [in] */1901 1, /* Turn on for "Forwardable ticket" [in] */1902 &fwdData ); /* Resulting response [out] */1903 1904 1905 if (retval) {1906 DEBUG(1,("ads_krb5_get_fwd_ticket: krb5_fwd_tgt_creds failed (%s)\n",1907 error_message(retval)));1908 goto out;1909 }1910 1911 if ((unsigned int)GSSAPI_CHECKSUM_SIZE + (unsigned int)fwdData.length <1912 (unsigned int)GSSAPI_CHECKSUM_SIZE) {1913 retval = EINVAL;1914 goto out;1915 }1916 1917 /* We're going to allocate a gssChecksum structure with a little1918 extra data the length of the kerberos credentials length1919 (APPLICATION 22) so that we can pack it on the end of the structure.1920 */1921 1922 pChksum = (char *)SMB_MALLOC(GSSAPI_CHECKSUM_SIZE + fwdData.length );1923 if (!pChksum) {1924 retval = ENOMEM;1925 goto out;1926 }1927 1928 p = pChksum;1929 1930 SIVAL(p, 0, GSSAPI_BNDLENGTH);1931 p += 4;1932 1933 /* Zero out the bindings fields */1934 memset(p, '\0', GSSAPI_BNDLENGTH );1935 p += GSSAPI_BNDLENGTH;1936 1937 SIVAL(p, 0, GSS_C_DELEG_FLAG );1938 p += 4;1939 SSVAL(p, 0, 1 );1940 p += 2;1941 SSVAL(p, 0, fwdData.length );1942 p += 2;1943 1944 /* Migrate the kerberos KRB_CRED data to the checksum delegation */1945 memcpy(p, fwdData.data, fwdData.length );1946 p += fwdData.length;1947 1948 /* We need to do this in order to allow our GSS-API */1949 retval = krb5_auth_con_set_req_cksumtype( context, *auth_context, GSSAPI_CHECKSUM );1950 if (retval) {1951 goto out;1952 }1953 1954 /* We now have a service ticket, now turn it into an AP-REQ. */1955 authenticator->length = fwdData.length + GSSAPI_CHECKSUM_SIZE;1956 1957 /* Caller should call free() when they're done with this. */1958 authenticator->data = (char *)pChksum;1959 1960 out:1961 1962 /* Remove that input data, we never needed it anyway. */1963 if (fwdData.length > 0) {1964 krb5_free_data_contents( context, &fwdData );1965 }1966 1967 return retval;1968 }1969 #endif1970 1969 1971 1970 #if defined(HAVE_KRB5_GET_CREDS_OPT_SET_IMPERSONATE) && \
Note:
See TracChangeset
for help on using the changeset viewer.