Further polish and docs for hierarchical capaths
This commit is contained in:
@@ -1673,6 +1673,7 @@ server_lookup:
|
||||
|
||||
if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
|
||||
if (capath == NULL) {
|
||||
/* With referalls, hierarchical capaths are always enabled */
|
||||
ret = _krb5_find_capath(context, tgt->crealm, our_realm,
|
||||
req_rlm, TRUE, &capath, &num_capath);
|
||||
if (ret)
|
||||
|
@@ -395,6 +395,14 @@ specifying order can be useful where tools read and write the
|
||||
configuration file without preserving parameter order.
|
||||
.Pp
|
||||
Malformed rules are ignored.
|
||||
.It Li allow_hierarchical_capaths = Va boolean
|
||||
When validating cross-realm transit paths, absent any explicit capath from the
|
||||
client realm to the server realm, allow a hierarchical transit path via the
|
||||
common ancestor domain of the two realms.
|
||||
Defaults to true.
|
||||
Note, absent an explicit setting, hierarchical capaths are always used by
|
||||
the KDC when generating a referral to a destination with which is no direct
|
||||
trust.
|
||||
.El
|
||||
.It Li [domain_realm]
|
||||
This is a list of mappings from DNS domain to Kerberos realm.
|
||||
|
@@ -411,14 +411,17 @@ _krb5_free_capath(krb5_context context, char **capath)
|
||||
struct hier_iter {
|
||||
const char *local_realm;
|
||||
const char *server_realm;
|
||||
const char *lr;
|
||||
const char *sr;
|
||||
size_t llen;
|
||||
size_t slen;
|
||||
size_t len;
|
||||
size_t num;
|
||||
const char *lr; /* Pointer into tail of local realm */
|
||||
const char *sr; /* Pointer into tail of server realm */
|
||||
size_t llen; /* Length of local_realm */
|
||||
size_t slen; /* Length of server_realm */
|
||||
size_t len; /* Length of common suffix */
|
||||
size_t num; /* Path element count */
|
||||
};
|
||||
|
||||
/*
|
||||
* Step up from local_realm to common suffix, or else down to server_realm.
|
||||
*/
|
||||
static const char *
|
||||
hier_next(struct hier_iter *state)
|
||||
{
|
||||
@@ -498,7 +501,7 @@ hier_init(struct hier_iter *state, const char *local_realm, const char *server_r
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a referral path from crealm to srealm via our_realm.
|
||||
* Find a referral path from client_realm to server_realm via local_realm.
|
||||
* Either via [capaths] or hierarchicaly.
|
||||
*/
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
@@ -506,12 +509,10 @@ _krb5_find_capath(krb5_context context,
|
||||
const char *client_realm,
|
||||
const char *local_realm,
|
||||
const char *server_realm,
|
||||
krb5_boolean use_hierachical,
|
||||
krb5_boolean use_hierarchical,
|
||||
char ***rpath,
|
||||
size_t *npath)
|
||||
{
|
||||
krb5_boolean maybe = (TRUE == 1) ? 2 : 1; /* Neither TRUE nor FALSE */
|
||||
krb5_boolean b;
|
||||
char **confpath;
|
||||
char **capath;
|
||||
struct hier_iter hier_state;
|
||||
@@ -529,9 +530,9 @@ _krb5_find_capath(krb5_context context,
|
||||
/*
|
||||
* With a [capaths] setting from the client to the server we look for our
|
||||
* own realm in the list. If our own realm is not present, we return the
|
||||
* first element. Otherwise, we return the next element, or possibly NULL.
|
||||
* Ignoring a [capaths] settings risks loops plus would violate explicit
|
||||
* policy and the principle of least surpise.
|
||||
* full list. Otherwise, we return our realm's successors, or possibly
|
||||
* NULL. Ignoring a [capaths] settings risks loops plus would violate
|
||||
* explicit policy and the principle of least surpise.
|
||||
*/
|
||||
if (confpath != NULL) {
|
||||
char **start = confpath;
|
||||
@@ -543,12 +544,16 @@ _krb5_find_capath(krb5_context context,
|
||||
start = rp+1;
|
||||
n = rp - start;
|
||||
|
||||
if (n == 0)
|
||||
if (n == 0) {
|
||||
krb5_config_free_strings(confpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
capath = calloc(n + 1, sizeof(*capath));
|
||||
if (capath == NULL)
|
||||
if (capath == NULL) {
|
||||
krb5_config_free_strings(confpath);
|
||||
return krb5_enomem(context);
|
||||
}
|
||||
|
||||
for (i = 0, rp = start; *rp; rp++) {
|
||||
if ((capath[i++] = strdup(*rp)) == NULL) {
|
||||
@@ -564,18 +569,17 @@ _krb5_find_capath(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* With hierarchical referrals, we ignore the client realm, and build a
|
||||
* path forward from our own realm!
|
||||
*/
|
||||
b = krb5_config_get_bool_default(context, NULL, maybe, "realms",
|
||||
local_realm, "hier_capaths", NULL);
|
||||
if (b == maybe)
|
||||
b = krb5_config_get_bool_default(context, NULL, TRUE, "libdefaults",
|
||||
"hier_capaths", NULL);
|
||||
if (b == FALSE)
|
||||
/* The use_hierarchical flag makes hierarchical path lookup unconditional */
|
||||
if (! use_hierarchical &&
|
||||
! krb5_config_get_bool_default(context, NULL, TRUE, "libdefaults",
|
||||
"allow_hierarchical_capaths", NULL))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* When validating transit paths, local_realm == client_realm. Otherwise,
|
||||
* with hierarchical referrals, they may differ, and we may be building a
|
||||
* path forward from our own realm!
|
||||
*/
|
||||
hier_init(&hier_state, local_realm, server_realm);
|
||||
if (hier_state.num == 0)
|
||||
return 0;
|
||||
@@ -610,8 +614,9 @@ krb5_check_transited(krb5_context context,
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
|
||||
/* In transit checks hierarchical capaths are optional */
|
||||
ret = _krb5_find_capath(context, client_realm, client_realm, server_realm,
|
||||
TRUE, &capath, &num_capath);
|
||||
FALSE, &capath, &num_capath);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@@ -410,7 +410,7 @@ struct entry libdefaults_entries[] = {
|
||||
{ "fcc-mit-ticketflags", krb5_config_string, check_boolean, 0 },
|
||||
{ "forward", krb5_config_string, check_boolean, 0 },
|
||||
{ "forwardable", krb5_config_string, check_boolean, 0 },
|
||||
{ "hier_capaths", krb5_config_string, check_boolean, 0 },
|
||||
{ "allow_hierarchical_capaths", krb5_config_string, check_boolean, 0 },
|
||||
{ "host_timeout", krb5_config_string, check_time, 0 },
|
||||
{ "http_proxy", krb5_config_string, check_host /* XXX */, 0 },
|
||||
{ "ignore_addresses", krb5_config_string, NULL, 0 },
|
||||
@@ -481,7 +481,7 @@ struct entry realms_entries[] = {
|
||||
{ "auth_to_local_names", krb5_config_string, NULL, 0 },
|
||||
{ "default_domain", krb5_config_string, NULL, 0 },
|
||||
{ "forwardable", krb5_config_string, check_boolean, 0 },
|
||||
{ "hier_capaths", krb5_config_string, check_boolean, 0 },
|
||||
{ "allow_hierarchical_capaths", krb5_config_string, check_boolean, 0 },
|
||||
{ "kdc", krb5_config_string, check_host, 0 },
|
||||
{ "kpasswd_server", krb5_config_string, check_host, 0 },
|
||||
{ "krb524_server", krb5_config_string, check_host, 0 },
|
||||
|
Reference in New Issue
Block a user