#ifndef LEAN_CLIENT
#include "k5-int.h"
#include "../krb/int-proto.h"
#include "../os/os-proto.h"
const char * KRB5_CALLCONV
krb5_kt_get_type (krb5_context context, krb5_keytab keytab)
{
return keytab->ops->prefix;
}
krb5_error_code KRB5_CALLCONV
krb5_kt_get_name(krb5_context context, krb5_keytab keytab, char *name,
unsigned int namelen)
{
return krb5_x((keytab)->ops->get_name,(context, keytab,name,namelen));
}
krb5_error_code KRB5_CALLCONV
krb5_kt_close(krb5_context context, krb5_keytab keytab)
{
return krb5_x((keytab)->ops->close,(context, keytab));
}
krb5_error_code KRB5_CALLCONV
krb5_kt_get_entry(krb5_context context, krb5_keytab keytab,
krb5_const_principal principal, krb5_kvno vno,
krb5_enctype enctype, krb5_keytab_entry *entry)
{
krb5_error_code err;
krb5_principal_data princ_data;
if (krb5_is_referral_realm(&principal->realm)) {
char *realm;
princ_data = *principal;
principal = &princ_data;
err = krb5_get_default_realm(context, &realm);
if (err)
return err;
princ_data.realm.data = realm;
princ_data.realm.length = strlen(realm);
}
err = krb5_x((keytab)->ops->get,(context, keytab, principal, vno, enctype,
entry));
TRACE_KT_GET_ENTRY(context, keytab, principal, vno, enctype, err);
if (principal == &princ_data)
krb5_free_default_realm(context, princ_data.realm.data);
return err;
}
krb5_error_code KRB5_CALLCONV
krb5_kt_start_seq_get(krb5_context context, krb5_keytab keytab,
krb5_kt_cursor *cursor)
{
return krb5_x((keytab)->ops->start_seq_get,(context, keytab, cursor));
}
krb5_error_code KRB5_CALLCONV
krb5_kt_next_entry(krb5_context context, krb5_keytab keytab,
krb5_keytab_entry *entry, krb5_kt_cursor *cursor)
{
return krb5_x((keytab)->ops->get_next,(context, keytab, entry, cursor));
}
krb5_error_code KRB5_CALLCONV
krb5_kt_end_seq_get(krb5_context context, krb5_keytab keytab,
krb5_kt_cursor *cursor)
{
return krb5_x((keytab)->ops->end_get,(context, keytab, cursor));
}
krb5_error_code KRB5_CALLCONV
krb5_kt_have_content(krb5_context context, krb5_keytab keytab)
{
krb5_keytab_entry entry;
krb5_kt_cursor cursor;
krb5_error_code ret;
char name[1024];
if (keytab->ops->start_seq_get == NULL)
return 0;
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
if (ret)
goto no_entries;
ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
krb5_kt_end_seq_get(context, keytab, &cursor);
if (ret)
goto no_entries;
krb5_kt_free_entry(context, &entry);
return 0;
no_entries:
if (krb5_kt_get_name(context, keytab, name, sizeof(name)) == 0) {
k5_setmsg(context, KRB5_KT_NOTFOUND,
_("Keytab %s is nonexistent or empty"), name);
}
return KRB5_KT_NOTFOUND;
}
static krb5_error_code
match_entries(krb5_context context, krb5_keytab keytab,
krb5_const_principal mprinc)
{
krb5_error_code ret;
krb5_keytab_entry ent;
krb5_kt_cursor cursor;
krb5_boolean match;
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
if (ret)
return ret;
while ((ret = krb5_kt_next_entry(context, keytab, &ent, &cursor)) == 0) {
match = krb5_sname_match(context, mprinc, ent.principal);
(void)krb5_free_keytab_entry_contents(context, &ent);
if (match)
break;
}
(void)krb5_kt_end_seq_get(context, keytab, &cursor);
if (ret && ret != KRB5_KT_END)
return ret;
return match ? 0 : KRB5_KT_NOTFOUND;
}
krb5_error_code
k5_kt_have_match(krb5_context context, krb5_keytab keytab,
krb5_principal mprinc)
{
krb5_error_code ret;
struct canonprinc iter = { mprinc, .no_hostrealm = TRUE };
krb5_const_principal canonprinc = NULL;
if (k5_sname_wildcard_host(context, mprinc))
return match_entries(context, keytab, mprinc);
while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 &&
canonprinc != NULL) {
ret = match_entries(context, keytab, canonprinc);
if (ret != KRB5_KT_NOTFOUND)
break;
}
free_canonprinc(&iter);
return (ret == 0 && canonprinc == NULL) ? KRB5_KT_NOTFOUND : ret;
}
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