/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
*
* Copyright 1990,1991,2008,2009 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.
*/
/*
*/
/* krb5_walk_realm_tree()
* krb5_free_realm_tree()
*
* internal function, used by krb5_get_cred_from_kdc()
*/
#include "k5-int.h"
#include "int-proto.h"
/* Solaris Kerberos */
#include <locale.h>
/*
* Structure to help with finding the common suffix between client and
* server realm during hierarchical traversal.
*/
struct hstate {
char *str;
char *tail;
char *dot;
};
static krb5_error_code
char **vals,
krb5_principal **tree);
static krb5_error_code
char ***vals);
static krb5_error_code
int sep);
static krb5_error_code
int sep);
static void
static krb5_error_code
int dotail,
int sep);
static void
static void
int realm_sep)
{
char **capvals;
/* Solaris Kerberos - enhance error message */
"Cannot find ticket for "
"requested realm: unknown "
"client and server"));
} else {
"Cannot find ticket for "
"requested realm: unknown "
"client"));
} else {
"Cannot find ticket for "
"requested realm: unknown "
"server"));
}
}
return KRB5_NO_TKT_IN_RLM;
}
return KRB5_NO_TKT_IN_RLM;
}
if (retval)
return retval;
return retval;
}
return retval;
}
/* ANL - Modified to allow Configurable Authentication Paths.
* This modification removes the restriction on the choice of realm
* names, i.e. they nolonger have to be hierarchical. This
* is allowed by RFC 1510: "If a hierarchical orginization is not used
* it may be necessary to consult some database in order to construct
* an authentication path between realms." The database is contained
* in the [capaths] section of the krb5.conf file.
* Client to server paths are defined. There are n**2 possible
* entries, but only those entries which are needed by the client
* or server need be present in its krb5.conf file. (n entries or 2*n
* entries if the same krb5.conf is used for clients and servers)
*
* for example: ESnet will be running a KDC which will share
* inter-realm keys with its many orginizations which include among
* other ANL, NERSC and PNL. Each of these orginizations wants to
* use its DNS name in the realm, ANL.GOV. In addition ANL wants
* to authenticatite to HAL.COM via a K5.MOON and K5.JUPITER
* A [capaths] section of the krb5.conf file for the ANL.GOV clients
* and servers would look like:
*
* [capaths]
* ANL.GOV = {
* NERSC.GOV = ES.NET
* PNL.GOV = ES.NET
* ES.NET = .
* HAL.COM = K5.MOON
* HAL.COM = K5.JUPITER
* }
* NERSC.GOV = {
* ANL.GOV = ES.NET
* }
* PNL.GOV = {
* ANL.GOV = ES.NET
* }
* ES.NET = {
* ANL.GOV = .
* }
* HAL.COM = {
* ANL.GOV = K5.JUPITER
* ANL.GOV = K5.MOON
* }
*
* In the above a "." is used to mean directly connected since the
* the profile routines cannot handle a null entry.
*
* If no client-to-server path is found, the default hierarchical path
* is still generated.
*
* This version of the Configurable Authentication Path modification
* differs from the previous versions prior to K5 beta 5 in that
* the profile routines are used, and the explicite path from
* client's realm to server's realm must be given. The modifications
* will work together.
* DEE - 5/23/95
*/
/*
* Build a tree given a set of profile values retrieved by
* walk_rtree_capath_vals().
*/
static krb5_error_code
char **vals,
{
;
nlinks = 0;
} else {
}
goto error;
}
for (i = 0; i < nprincs + 1; i++)
/* Invariant: PPRINC points one past end of list. */
/* Local TGS name */
for (i = 0; i < nlinks; i++) {
}
if (retval) {
/* krb5_free_principal() correctly handles null input */
}
}
return retval;
}
/*
* Get realm list from "capaths" section of the profile. Deliberately
* returns success but leaves VALS null if profile_get_values() fails
* by not finding anything.
*/
static krb5_error_code
char ***vals)
{
/* null-terminated realm names */
goto error;
}
goto error;
}
key[0] = "capaths";
switch (retval) {
case PROF_NO_SECTION:
case PROF_NO_RELATION:
/*
* Not found; don't return an error.
*/
retval = 0;
break;
default:
break;
}
return retval;
}
/*
* Build tree by hierarchical traversal.
*/
static krb5_error_code
int sep)
{
if (retval)
return retval;
goto error;
}
for (i = 0; i < nrealms; i++)
for (i = 0; i < nrealms; i++) {
}
return 0;
}
return retval;
}
/*
* Construct list of realms between client and server.
*/
static krb5_error_code
int sep)
{
struct hstate c, s;
*nrealms = 0;
if (r == NULL) {
goto error;
}
/* Copy client realm "tweens" forward. */
rp++;
}
/* Copy server realm "tweens" backward. */
rp++;
}
if (retval) {
return retval;
}
*realms = r;
return 0;
}
static void
{
size_t i;
for (i = 0; i < nrealms; i++)
}
/*
* Build a list of realms between a given realm and the common
* suffix. The original realm is included, but the "tail" is only
* included if DOTAIL is true.
*
* Warning: This function intentionally aliases memory. Caller must
* make copies as needed and not call krb5_free_data_contents, etc.
*/
static krb5_error_code
int dotail,
int sep)
{
*ntweens = n = 0;
continue;
break;
return ENOMEM;
}
n++;
break;
lp = &p[1];
}
*ntweens = n;
return 0;
}
/*
* Adjust suffixes that each starts at the beginning of a component,
* to avoid the problem where "BC.EXAMPLE.COM" is erroneously reported
* as a parent of "ABC.EXAMPLE.COM".
*/
static void
{
return;
/*
* Is it a full component? Yes, if it's the beginning of the
* string or there's a separator to the left.
*
* The index of -1 is valid because it only gets evaluated if the
* pointer is not at the beginning of the string.
*/
/*
* If they're both full components, we're done.
*/
return;
/*
* Out of bounds? Can only happen if there are trailing dots.
*/
}
} else {
}
}
/*
* Find common suffix of C and S.
*
* C->TAIL and S->TAIL will point to the respective suffixes. C->DOT
* and S->DOT will point to the nearest instances of SEP to the right
* of the start of each suffix. Caller must initialize TAIL and DOT
* pointers to null.
*/
static void
{
return;
/*
* before the beginning of an array.
*/
/*
* Set CP and SP to point to the common suffix of each string.
* When we run into separators (dots, unless someone has a X.500
* style realm), keep pointers to the latest pair.
*/
/*
* Didn't match, so most recent match is one byte to the
* right (or not at all).
*/
cp++;
sp++;
break;
}
/*
* Keep track of matching dots.
*/
}
}
/* No match found at all. */
return;
}
void
{
return;
while (*nrealms) {
nrealms++;
}
}