If the name in the acceptor credential has not been specified yet (because the gss-accept-sec-context call was not run yet), a call to gss_inquire_cred using this credential must return the principal name from the first entry in the associated keytab. I have discussed this implementation with Greg Hudson. Index: src/lib/gssapi/krb5/inq_cred.c =================================================================== --- src/lib/gssapi/krb5/inq_cred.c (revision 56276) +++ src/lib/gssapi/krb5/inq_cred.c (working copy) @@ -145,15 +145,30 @@ lifetime = GSS_C_INDEFINITE; if (name) { - if (cred->name && - (code = kg_duplicate_name(context, cred->name, - KG_INIT_NAME_INTERN, &ret_name))) { - k5_mutex_unlock(&cred->lock); - *minor_status = code; - save_error_info(*minor_status, context); - ret = GSS_S_FAILURE; - goto fail; + if (cred->name) + { + if (code = kg_duplicate_name(context, cred->name, + KG_INIT_NAME_INTERN, &ret_name)) { + k5_mutex_unlock(&cred->lock); + *minor_status = code; + save_error_info(*minor_status, context); + ret = GSS_S_FAILURE; + goto fail; + } } + else if ((cred->usage == GSS_C_ACCEPT ||cred->usage == GSS_C_BOTH) && + cred->keytab != NULL) + { + if (code = kg_get_principal_name_from_keytab(context, cred->keytab, + KG_INIT_NAME_INTERN, + &ret_name)) { + k5_mutex_unlock(&cred->lock); + *minor_status = code; + save_error_info(*minor_status, context); + ret = GSS_S_FAILURE; + goto fail; + } + } } if (mechanisms) { Index: src/lib/gssapi/krb5/gssapiP_krb5.h =================================================================== --- src/lib/gssapi/krb5/gssapiP_krb5.h (revision 56276) +++ src/lib/gssapi/krb5/gssapiP_krb5.h (working copy) @@ -892,6 +892,12 @@ gss_name_t name, gss_buffer_t exp_composite_name); +krb5_error_code +kg_get_principal_name_from_keytab(krb5_context context, + krb5_keytab kt, + krb5_flags flags, + krb5_gss_name_t* dst); + OM_uint32 krb5_gss_map_name_to_any(OM_uint32 *minor_status, gss_name_t name, Index: src/lib/gssapi/krb5/naming_exts.c =================================================================== --- src/lib/gssapi/krb5/naming_exts.c (revision 56276) +++ src/lib/gssapi/krb5/naming_exts.c (working copy) @@ -720,3 +720,55 @@ } #endif +krb5_error_code +kg_get_principal_name_from_keytab(krb5_context context, + krb5_keytab kt, + krb5_flags flags, + krb5_gss_name_t* dst) +{ + krb5_error_code code; + krb5_kt_cursor cursor; + krb5_keytab_entry entry; + krb5_keytab_entry* pEntry = NULL; + krb5_gss_name_t name; + int end_seq = 0; + + code = krb5_kt_start_seq_get(context, kt, &cursor); + if (code != 0) + { + goto cleanup; + } + + end_seq = 1; + + code = krb5_kt_next_entry(context, kt, &entry, &cursor); + if (code != 0) + { + goto cleanup; + } + + pEntry = &entry; + + code = kg_init_name(context, entry.principal, NULL, flags, &name); + if (code != 0) + { + goto cleanup; + } + + *dst = name; + +cleanup: + + if (pEntry) + { + (void) krb5_free_keytab_entry_contents(context, pEntry); + } + + if (end_seq) + { + (void) krb5_kt_end_seq_get(context, kt, &cursor); + } + + return code; +} +