summaryrefslogtreecommitdiffstats
path: root/source4/libcli/auth/clikrb5.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli/auth/clikrb5.c')
-rw-r--r--source4/libcli/auth/clikrb5.c98
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 )
{