diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/configure.in | 57 | ||||
-rw-r--r-- | source3/include/includes.h | 9 | ||||
-rw-r--r-- | source3/libsmb/clikrb5.c | 103 |
3 files changed, 107 insertions, 62 deletions
diff --git a/source3/configure.in b/source3/configure.in index 314582c449..7c257afe6e 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -3439,6 +3439,7 @@ if test x"$with_ads_support" != x"no"; then AC_CHECK_FUNC_EXT(krb5_set_real_time, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_set_default_in_tkt_etypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_set_default_tgs_enctypes, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_set_default_tgs_ktypes, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_principal2salt, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_use_enctype, $KRB5_LIBS) @@ -3450,20 +3451,18 @@ if test x"$with_ads_support" != x"no"; then AC_CHECK_FUNC_EXT(krb5_locate_kdc, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_get_permitted_enctypes, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_get_default_in_tkt_etypes, $KRB5_LIBS) - AC_CHECK_FUNC_EXT(krb5_free_ktypes, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_free_data_contents, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_principal_get_comp_string, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_free_unparsed_name, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_free_keytab_entry_contents, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_kt_free_entry, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_krbhst_init, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_krbhst_get_addrinfo, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_c_enctype_compare, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_enctypes_compatible_keys, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_crypto_init, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_crypto_destroy, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_decode_ap_req, $KRB5_LIBS) - AC_CHECK_FUNC_EXT(decode_krb5_ap_req, $KRB5_LIBS) - AC_CHECK_FUNC_EXT(krb5_free_ap_req, $KRB5_LIBS) AC_CHECK_FUNC_EXT(free_AP_REQ, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_c_verify_checksum, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_principal_compare_any_realm, $KRB5_LIBS) @@ -3473,9 +3472,34 @@ if test x"$with_ads_support" != x"no"; then AC_CHECK_FUNC_EXT(krb5_get_renewed_creds, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_get_kdc_cred, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_free_error_contents, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(initialize_krb5_error_table, $KRB5_LIBS) LIBS="$KRB5_LIBS $LIBS" + AC_CACHE_CHECK(whether krb5_ticket contains kvno and enctype, + smb_krb5_ticket_has_keyinfo, + [ + AC_TRY_COMPILE( + [ + #include <krb5.h> + ], + [ + krb5_ticket ticket; + krb5_kvno kvno; + krb5_enctype enctype; + + enctype = ticket.enc_part.enctype; + kvno = ticket.enc_part.kvno; + ], + [ smb_krb5_ticket_has_keyinfo=yes ], + [ smb_krb5_ticket_has_keyinfo=no ]) + ]) + + if test x"$smb_krb5_ticket_has_keyinfo" = x"yes" ; then + AC_DEFINE(KRB5_TICKET_HAS_KEYINFO, 1, + [Whether the krb5_ticket structure contains the kvno and enctype]) + fi + AC_CACHE_CHECK(whether krb5_verify_checksum takes 7 arguments, smb_krb5_verify_checksum, [ AC_TRY_COMPILE([ #include <krb5.h>], @@ -3832,18 +3856,23 @@ if test x"$with_ads_support" != x"no"; then use_ads=no fi - if test x"$ac_cv_func_ext_krb5_free_ap_req" != x"yes" -a \ - x"$ac_cv_func_ext_free_AP_REQ" != x"yes" - then - AC_MSG_WARN(no KRB5_AP_REQ_FREE_FUNCTION detected) - use_ads=no - fi + if test x"$smb_krb5_ticket_has_keyinfo" != x"yes" ; then + + # We only need the following functions if we can't get the enctype + # and kvno out of the ticket directly (ie. on Heimdal). + + if test x"$ac_cv_func_ext_free_AP_REQ" != x"yes" + then + AC_MSG_WARN(no KRB5_AP_REQ_FREE_FUNCTION detected) + use_ads=no + fi + + if test x"$ac_cv_func_ext_decode_krb5_ap_req" != x"yes" + then + AC_MSG_WARN(no KRB5_AP_REQ_DECODING_FUNCTION detected) + use_ads=no + fi - if test x"$ac_cv_func_ext_krb5_decode_ap_req" != x"yes" -a \ - x"$ac_cv_func_ext_decode_krb5_ap_req" != x"yes" - then - AC_MSG_WARN(no KRB5_AP_REQ_DECODING_FUNCTION detected) - use_ads=no fi if test x"$use_ads" = x"yes"; then diff --git a/source3/include/includes.h b/source3/include/includes.h index 0f7b2d86d0..b695253f12 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -1105,6 +1105,14 @@ krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_con void krb5_free_unparsed_name(krb5_context ctx, char *val); #endif +/* Stub out initialize_krb5_error_table since it is not present in all + * Kerberos implementations. If it's not present, it's not necessary to + * call it. + */ +#ifndef HAVE_INITIALIZE_KRB5_ERROR_TABLE +#define initialize_krb5_error_table() +#endif + /* Samba wrapper function for krb5 functionality. */ void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr); int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype); @@ -1113,7 +1121,6 @@ BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_tick krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt); krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters); krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes); -void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes); BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote); krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry); krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, krb5_principal host_princ, int enctype); diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 44713784f4..2415b28160 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -130,12 +130,34 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, } #endif -#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) +#if !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) + +#if defined(HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES) + +/* With MIT kerberos, we should use krb5_set_default_tgs_enctypes in preference + * to krb5_set_default_tgs_ktypes. See + * http://lists.samba.org/archive/samba-technical/2006-July/048271.html + * + * If the MIT libraries are not exporting internal symbols, we will end up in + * this branch, which is correct. Otherwise we will continue to use the + * internal symbol + */ + krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) +{ + return krb5_set_default_tgs_enctypes(ctx, enc); +} + +#elif defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) + +/* Heimdal */ krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) { return krb5_set_default_in_tkt_etypes(ctx, enc); } -#endif + +#endif /* HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES */ + +#endif /* HAVE_KRB5_SET_DEFAULT_TGS_KTYPES */ #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* HEIMDAL */ @@ -239,18 +261,6 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, #error UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif - void free_kerberos_etypes(krb5_context context, - krb5_enctype *enctypes) -{ -#if defined(HAVE_KRB5_FREE_KTYPES) - krb5_free_ktypes(context, enctypes); - return; -#else - SAFE_FREE(enctypes); - return; -#endif -} - #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, @@ -373,6 +383,14 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ } #if !defined(HAVE_KRB5_LOCATE_KDC) + +/* krb5_locate_kdc is an internal MIT symbol. MIT are not yet willing to commit + * to a public interface for this functionality, so we have to be able to live + * without it if the MIT libraries are hiding their internal symbols. + */ + +#if defined(KRB5_KRBHST_INIT) +/* Heimdal */ krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) { krb5_krbhst_handle hnd; @@ -431,7 +449,19 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ *addr_pp = sa; return 0; } -#endif + +#else /* ! defined(KRB5_KRBHST_INIT) */ + + krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, + struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + DEBUG(0, ("unable to explicitly locate the KDC on this platform\n")); + return KRB5_KDC_UNREACH; +} + +#endif /* KRB5_KRBHST_INIT */ + +#endif /* HAVE_KRB5_LOCATE_KDC */ #if !defined(HAVE_KRB5_FREE_UNPARSED_NAME) void krb5_free_unparsed_name(krb5_context context, char *val) @@ -906,31 +936,16 @@ out: return ret; } - void smb_krb5_free_ap_req(krb5_context context, - krb5_ap_req *ap_req) -{ -#ifdef HAVE_KRB5_FREE_AP_REQ /* MIT */ - krb5_free_ap_req(context, ap_req); -#elif defined(HAVE_FREE_AP_REQ) /* Heimdal */ - free_AP_REQ(ap_req); -#else -#error UNKNOWN_KRB5_AP_REQ_FREE_FUNCTION -#endif -} - /* Prototypes */ -#if defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */ -krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); -#endif krb5_error_code smb_krb5_get_keyinfo_from_ap_req(krb5_context context, const krb5_data *inbuf, krb5_kvno *kvno, krb5_enctype *enctype) { - krb5_error_code ret; #ifdef HAVE_KRB5_DECODE_AP_REQ /* Heimdal */ { + krb5_error_code ret; krb5_ap_req ap_req; ret = krb5_decode_ap_req(context, inbuf, &ap_req); @@ -941,24 +956,13 @@ krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); *enctype = get_enctype_from_ap_req(&ap_req); smb_krb5_free_ap_req(context, &ap_req); + free_AP_REQ(ap_req); + return 0; } -#elif defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */ - { - krb5_ap_req *ap_req = NULL; - - ret = decode_krb5_ap_req(inbuf, &ap_req); - if (ret) - return ret; - - *kvno = get_kvno_from_ap_req(ap_req); - *enctype = get_enctype_from_ap_req(ap_req); - - smb_krb5_free_ap_req(context, ap_req); - } -#else -#error UNKNOWN_KRB5_AP_REQ_DECODING_FUNCTION #endif - return ret; + + /* Possibly not an appropriate error code. */ + return KRB5KDC_ERR_BADOPTION; } krb5_error_code krb5_rd_req_return_keyblock_from_keytab(krb5_context context, @@ -986,10 +990,15 @@ krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); return ret; } +#ifdef KRB5_TICKET_HAS_KEYINFO + enctype = (*ticket)->enc_part.enctype; + kvno = (*ticket)->enc_part.kvno; +#else ret = smb_krb5_get_keyinfo_from_ap_req(context, inbuf, &kvno, &enctype); if (ret) { return ret; } +#endif ret = get_key_from_keytab(context, server, |