Revision 784c38f50e70a739400cdd3f2620bac2e2788e6c authored by Greg Hudson on 01 August 2024, 06:41:15 UTC, committed by Greg Hudson on 05 August 2024, 21:11:01 UTC
Edit the block comment above k5_sendto() to take into account commits 802318cda963456b3ed7856c836e89da891483be (which added request_timeout) and 6436a3808061da787a43c6810f5f0370cdfb6e36 (which made the open TCP connection wait indefinite).
1 parent 2063e72
ktfns.c
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* lib/krb5/keytab/ktfns.c */
/*
* Copyright 2001,2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*/
/*
* Dispatch methods for keytab code.
*/
#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 the keytab is not iterable, assume that it has content. */
if (keytab->ops->start_seq_get == NULL)
return 0;
/* See if we can get at least one entry via iteration. */
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;
/* Scan the keytab for host-based entries matching accprinc. */
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;
/* Don't try to canonicalize if we're going to ignore hostnames. */
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;
}
/*
* 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 */

Computing file changes ...