diff options
author | Andrew Bartlett <abartlet@samba.org> | 2004-12-24 09:54:23 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:07:37 -0500 |
commit | 44113c4de1ae06a78a940782dc762b6576310d0d (patch) | |
tree | 7d6e30dc5a56b11edcd2def2304aa78071b1405e /source4/libcli/auth/clikrb5.c | |
parent | bebe512a57c6aabe6cd539750834297a17b5c4f5 (diff) | |
download | samba-44113c4de1ae06a78a940782dc762b6576310d0d.tar.gz samba-44113c4de1ae06a78a940782dc762b6576310d0d.tar.xz samba-44113c4de1ae06a78a940782dc762b6576310d0d.zip |
r4355: More work from the elves on Christmas eve:
- Update Samba4's kerberos code to match the 'salting' changes in
Samba3 (and many other cleanups by jra).
- Move GENSEC into the modern era of talloc destructors. This avoids
many of the memory leaks in this code, as we now can't somehow
'forget' to call the end routine.
- This required fixing some of the talloc hierarchies.
- The new krb5 seems more sensitive to getting the service name
right, so start actually setting the service name on the krb5 context.
Andrew Bartlett
(This used to be commit 278bf1a61a6da6ef955a12c13d7b1a0357cebf1f)
Diffstat (limited to 'source4/libcli/auth/clikrb5.c')
-rw-r--r-- | source4/libcli/auth/clikrb5.c | 98 |
1 files changed, 76 insertions, 22 deletions
diff --git a/source4/libcli/auth/clikrb5.c b/source4/libcli/auth/clikrb5.c index 7ad8dd7b6c..122f9510e7 100644 --- a/source4/libcli/auth/clikrb5.c +++ b/source4/libcli/auth/clikrb5.c @@ -71,11 +71,11 @@ pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); } #else - __ERROR__XX__UNKNOWN_ADDRTYPE +#error UNKNOWN_ADDRTYPE #endif -#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) - int create_kerberos_key_from_string(krb5_context context, +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) && defined(HAVE_KRB5_ENCRYPT_BLOCK) + int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, @@ -96,7 +96,7 @@ return ret; } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) - int create_kerberos_key_from_string(krb5_context context, + int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, @@ -114,9 +114,30 @@ salt, key); } #else - __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#error UNKNOWN_CREATE_KEY_FUNCTIONS #endif + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) +{ + krb5_principal salt_princ = NULL; + int ret; + /* + * Check if we've determined that the KDC is salting keys for this + * principal/enctype in a non-obvious way. If it is, try to match + * its behavior. + */ + salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype); + ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype); + if (salt_princ) { + krb5_free_principal(context, salt_princ); + } + return ret; +} + #if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes) @@ -190,7 +211,7 @@ krb5_error_code rc; int num_kdcs, i; struct sockaddr *sa; - struct addrinfo **ai; + struct addrinfo *ai; *addr_pp = NULL; *naddrs = 0; @@ -220,16 +241,15 @@ return -1; } - *addr_pp = malloc_array_p(struct sockaddr, num_kdcs); - memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + memset(sa, '\0', sizeof(struct sockaddr) * num_kdcs ); for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { #if defined(HAVE_KRB5_KRBHST_GET_ADDRINFO) - rc = krb5_krbhst_get_addrinfo(ctx, hinfo, ai); + rc = krb5_krbhst_get_addrinfo(ctx, hinfo, &ai); if (rc) { DEBUG(0,("krb5_krbhst_get_addrinfo failed: %s\n", error_message(rc))); - return rc; + continue; } #endif if (hinfo->ai && hinfo->ai->ai_family == AF_INET) @@ -251,6 +271,42 @@ } #endif + void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) +{ +#if defined(HAVE_KRB5_FREE_DATA_CONTENTS) + if (pdata->data) { + krb5_free_data_contents(context, pdata); + } +#else + SAFE_FREE(pdata->data); +#endif +} + + void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) +{ +#if defined(HAVE_KRB5_KEYBLOCK_IN_CREDS) + KRB5_KEY_TYPE((&pcreds->keyblock)) = enctype; +#elif defined(HAVE_KRB5_SESSION_IN_CREDS) + KRB5_KEY_TYPE((&pcreds->session)) = enctype; +#else +#error UNKNOWN_KEYBLOCK_MEMBER_IN_KRB5_CREDS_STRUCT +#endif +} + + BOOL kerberos_compatible_enctypes(krb5_context context, + krb5_enctype enctype1, + krb5_enctype enctype2) +{ +#if defined(HAVE_KRB5_C_ENCTYPE_COMPARE) + krb5_boolean similar = 0; + + krb5_c_enctype_compare(context, enctype1, enctype2, &similar); + return similar ? True : False; +#elif defined(HAVE_KRB5_ENCTYPES_COMPATIBLE_KEYS) + return krb5_enctypes_compatible_keys(context, enctype1, enctype2) ? True : False; +#endif +} + static BOOL ads_cleanup_expired_creds(krb5_context context, krb5_ccache ccache, krb5_creds *credsp) @@ -279,13 +335,13 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, we're using creds obtained outside of our exectuable */ if (StrCaseCmp(krb5_cc_get_type(context, ccache), "FILE") == 0) { - DEBUG(5, ("We do not remove creds from a FILE ccache\n")); + DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a FILE ccache\n")); return False; } retval = krb5_cc_remove_cred(context, ccache, 0, credsp); if (retval) { - DEBUG(1, ("krb5_cc_remove_cred failed, err %s\n", + DEBUG(1, ("ads_cleanup_expired_creds: krb5_cc_remove_cred failed, err %s\n", error_message(retval))); /* If we have an error in this, we want to display it, but continue as though we deleted it */ @@ -296,7 +352,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ - krb5_error_code ads_krb5_mk_req(krb5_context context, +krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, const char *principal, @@ -314,7 +370,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, retval = krb5_parse_name(context, principal, &server); if (retval) { - DEBUG(1,("Failed to parse principal %s\n", principal)); + DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal)); return retval; } @@ -327,7 +383,9 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, } if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { - DEBUG(10,("krb5_cc_get_principal failed (%s)\n", + /* This can commonly fail on smbd startup with no ticket in the cache. + * Report at higher level than 1. */ + DEBUG(3,("ads_krb5_mk_req: krb5_cc_get_principal failed (%s)\n", error_message(retval))); goto cleanup_creds; } @@ -335,7 +393,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, while(!creds_ready) { if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { - DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", + DEBUG(1,("ads_krb5_mk_req: krb5_get_credentials failed for %s (%s)\n", principal, error_message(retval))); goto cleanup_creds; } @@ -344,7 +402,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, if ((unsigned)credsp->times.starttime > time(NULL)) { time_t t = time(NULL); int time_offset =(unsigned)credsp->times.starttime-t; - DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + DEBUG(4,("ads_krb5_mk_req: Advancing clock by %d seconds to cope with clock skew\n", time_offset)); krb5_set_real_time(context, t + time_offset + 1, 0); } @@ -366,7 +424,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); if (retval) { - DEBUG(1,("krb5_mk_req_extended failed (%s)\n", + DEBUG(1,("ads_krb5_mk_req: krb5_mk_req_extended failed (%s)\n", error_message(retval))); } @@ -378,13 +436,9 @@ cleanup_creds: cleanup_princ: krb5_free_principal(context, server); - if (mem_ctx) { - talloc_destroy(mem_ctx); - } return retval; } - #if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) { |