diff options
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 ) { |