aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Howard <lukeh@padl.com>2011-04-11 09:01:07 +0000
committerLuke Howard <lukeh@padl.com>2011-04-11 09:01:07 +0000
commit6caecfb3e212de4eca9148c23996b5a727af473e (patch)
tree847606828c5454a8d5bf0261c5608a039c420060
parent3de9ede67a53bc11e56e28ca4945a91eaee0b1a7 (diff)
downloadkrb5-6caecfb3e212de4eca9148c23996b5a727af473e.zip
krb5-6caecfb3e212de4eca9148c23996b5a727af473e.tar.gz
krb5-6caecfb3e212de4eca9148c23996b5a727af473e.tar.bz2
Merge branch 'master' into users/lhoward/saml2
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/saml2@24871 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/include/k5-int.h3
-rw-r--r--src/lib/gssapi/krb5/inq_cred.c22
-rw-r--r--src/lib/krb5/keytab/ktfns.c34
-rw-r--r--src/lib/krb5/krb/vfy_increds.c25
-rw-r--r--src/lib/krb5/libkrb5.exports1
-rw-r--r--src/lib/krb5_32.def1
6 files changed, 60 insertions, 26 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 5e1324b..29f6ae5 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -2618,6 +2618,9 @@ krb5_error_code krb5_generate_seq_number(krb5_context, const krb5_keyblock *,
krb5_error_code KRB5_CALLCONV krb5_kt_register(krb5_context,
const struct _krb5_kt_ops *);
+krb5_error_code k5_kt_get_principal(krb5_context context, krb5_keytab keytab,
+ krb5_principal *princ_out);
+
krb5_error_code krb5_principal2salt_norealm(krb5_context, krb5_const_principal,
krb5_data *);
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
index 493dd03..4ef94c7 100644
--- a/src/lib/gssapi/krb5/inq_cred.c
+++ b/src/lib/gssapi/krb5/inq_cred.c
@@ -88,6 +88,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
krb5_timestamp now;
krb5_deltat lifetime;
krb5_gss_name_t ret_name;
+ krb5_principal princ;
gss_OID_set mechs;
OM_uint32 ret;
@@ -144,9 +145,24 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
lifetime = GSS_C_INDEFINITE;
if (name) {
- if (cred->name &&
- (code = kg_duplicate_name(context, cred->name,
- KG_INIT_NAME_INTERN, &ret_name))) {
+ if (cred->name) {
+ code = kg_duplicate_name(context, cred->name, KG_INIT_NAME_INTERN,
+ &ret_name);
+ } else if ((cred->usage == GSS_C_ACCEPT || cred->usage == GSS_C_BOTH)
+ && cred->keytab != NULL) {
+ /* This is a default acceptor cred; use a name from the keytab if
+ * we can. */
+ code = k5_kt_get_principal(context, cred->keytab, &princ);
+ if (code == 0) {
+ code = kg_init_name(context, princ, NULL, NULL, NULL,
+ KG_INIT_NAME_NO_COPY | KG_INIT_NAME_INTERN,
+ &ret_name);
+ if (code)
+ krb5_free_principal(context, princ);
+ } else if (code == KRB5_KT_NOTFOUND)
+ code = 0;
+ }
+ if (code) {
k5_mutex_unlock(&cred->lock);
*minor_status = code;
save_error_info(*minor_status, context);
diff --git a/src/lib/krb5/keytab/ktfns.c b/src/lib/krb5/keytab/ktfns.c
index a06689c..ecf0acf 100644
--- a/src/lib/krb5/keytab/ktfns.c
+++ b/src/lib/krb5/keytab/ktfns.c
@@ -97,4 +97,38 @@ krb5_kt_end_seq_get(krb5_context context, krb5_keytab keytab,
{
return krb5_x((keytab)->ops->end_get,(context, keytab, cursor));
}
+
+/*
+ * In a couple of places we need to get a principal name from a keytab: when
+ * verifying credentials against a keytab, and when querying the name of a
+ * default GSS acceptor cred. Keytabs do not have the concept of a default
+ * principal like ccaches do, so for now we just return the first principal
+ * listed in the keytab, or an error if it's not iterable. In the future we
+ * could consider elevating this to a public API and giving keytab types an
+ * operation to return a default principal, and maybe extending the file format
+ * and tools to support it. Returns KRB5_KT_NOTFOUND if the keytab is empty
+ * or non-iterable.
+ */
+krb5_error_code
+k5_kt_get_principal(krb5_context context, krb5_keytab keytab,
+ krb5_principal *princ_out)
+{
+ krb5_error_code ret;
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry kte;
+
+ *princ_out = NULL;
+ if (keytab->ops->start_seq_get == NULL)
+ return KRB5_KT_NOTFOUND;
+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if (ret)
+ return ret;
+ ret = krb5_kt_next_entry(context, keytab, &kte, &cursor);
+ (void)krb5_kt_end_seq_get(context, keytab, &cursor);
+ if (ret)
+ return (ret == KRB5_KT_END) ? KRB5_KT_NOTFOUND : ret;
+ ret = krb5_copy_principal(context, kte.principal, princ_out);
+ krb5_kt_free_entry(context, &kte);
+ return ret;
+}
#endif /* LEAN_CLIENT */
diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c
index 1f4313f..207b309 100644
--- a/src/lib/krb5/krb/vfy_increds.c
+++ b/src/lib/krb5/krb/vfy_increds.c
@@ -20,27 +20,6 @@ nofail(krb5_context context, krb5_verify_init_creds_opt *options,
return FALSE;
}
-/* Set *server_out to the first principal name in keytab. */
-static krb5_error_code
-get_first_keytab_princ(krb5_context context, krb5_keytab keytab,
- krb5_principal *server_out)
-{
- krb5_error_code ret;
- krb5_kt_cursor cursor;
- krb5_keytab_entry kte;
-
- ret = krb5_kt_start_seq_get(context, keytab, &cursor);
- if (ret)
- return ret;
- ret = krb5_kt_next_entry(context, keytab, &kte, &cursor);
- (void)krb5_kt_end_seq_get(context, keytab, &cursor);
- if (ret)
- return ret;
- ret = krb5_copy_principal(context, kte.principal, server_out);
- krb5_kt_free_entry(context, &kte);
- return ret;
-}
-
static krb5_error_code
copy_creds_except(krb5_context context, krb5_ccache incc,
krb5_ccache outcc, krb5_principal princ)
@@ -128,8 +107,8 @@ krb5_verify_init_creds(krb5_context context,
if (ret)
goto cleanup;
} else {
- /* Use the first principal name in the keytab. */
- ret = get_first_keytab_princ(context, keytab, &server);
+ /* Use a principal name from the keytab. */
+ ret = k5_kt_get_principal(context, keytab, &server);
if (ret) {
/* There's no keytab, or it's empty, or we can't read it.
* Allow this unless configuration demands verification. */
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
index 98f914d..b531b70 100644
--- a/src/lib/krb5/libkrb5.exports
+++ b/src/lib/krb5/libkrb5.exports
@@ -108,6 +108,7 @@ initialize_k5e1_error_table
initialize_kv5m_error_table
initialize_prof_error_table
k5_free_serverlist
+k5_kt_get_principal
k5_locate_kdc
k5_plugin_free_modules
k5_plugin_load
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
index 8c8a8f5..032faf7 100644
--- a/src/lib/krb5_32.def
+++ b/src/lib/krb5_32.def
@@ -408,3 +408,4 @@ EXPORTS
; new in 1.10
krb5_sname_match @384
+ k5_kt_get_principal @385 ; PRIVATE GSSAPI