summaryrefslogtreecommitdiffstats
path: root/src/kdc
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2013-01-11 13:26:37 -0500
committerGreg Hudson <ghudson@mit.edu>2013-01-11 13:36:20 -0500
commitc53ea7bef444d7c151c46224b7a0600b9539496f (patch)
tree3656a64e4b36945f174d145e9f2cbac84ca11d44 /src/kdc
parent59ff1102942b564faa257c9f283efeb6fea63b8f (diff)
downloadkrb5-c53ea7bef444d7c151c46224b7a0600b9539496f.tar.gz
krb5-c53ea7bef444d7c151c46224b7a0600b9539496f.tar.xz
krb5-c53ea7bef444d7c151c46224b7a0600b9539496f.zip
Simplify KDC host referral code
Remove some unnecessary optimizations to reduce code complexity. Get rid of krb5_match_config_pattern in favor of a simpler helper function in do_tgs_req_c. Get rid of KRB5_CONF_ASTERISK and just use "*" instead. Use a helper function to combine [kdcdefaults] and realm subsection values of variables, and don't bother adding leading and trailing spaces. Consistently use the names "hostbased" and "no_referral" to refer to variable values (with a "realm_" prefix for structures which currently use it).
Diffstat (limited to 'src/kdc')
-rw-r--r--src/kdc/do_tgs_req.c36
-rw-r--r--src/kdc/main.c127
-rw-r--r--src/kdc/realm_data.h7
3 files changed, 64 insertions, 106 deletions
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 1d56566407..1e7331347a 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -1063,6 +1063,24 @@ cleanup:
return retval;
}
+/* Return true if item is an element of the space/comma-separated list. */
+static krb5_boolean
+in_list(const char *list, const char *item)
+{
+ const char *p;
+ int len = strlen(item);
+
+ if (list == NULL)
+ return FALSE;
+ for (p = strstr(list, item); p != NULL; p = strstr(p + 1, item)) {
+ if ((p == list || isspace((unsigned char)p[-1]) || p[-1] == ',') &&
+ (p[len] == '\0' || isspace((unsigned char)p[len]) ||
+ p[len] == ','))
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*
* Check whether the request satisfies the conditions for generating a referral
* TGT. The caller checks whether the hostname component looks like a FQDN.
@@ -1072,8 +1090,8 @@ is_referral_req(kdc_realm_t *kdc_active_realm, krb5_kdc_req *request)
{
krb5_boolean ret = FALSE;
char *stype = NULL;
- char *ref_services = kdc_active_realm->realm_host_based_services;
- char *nonref_services = kdc_active_realm->realm_no_host_referral;
+ char *hostbased = kdc_active_realm->realm_hostbased;
+ char *no_referral = kdc_active_realm->realm_no_referral;
if (!(request->kdc_options & KDC_OPT_CANONICALIZE))
return FALSE;
@@ -1090,22 +1108,14 @@ is_referral_req(kdc_realm_t *kdc_active_realm, krb5_kdc_req *request)
switch (krb5_princ_type(kdc_context, request->server)) {
case KRB5_NT_UNKNOWN:
/* Allow referrals for NT-UNKNOWN principals, if configured. */
- if (kdc_active_realm->realm_host_based_services != NULL) {
- if (!krb5_match_config_pattern(ref_services, stype) &&
- !krb5_match_config_pattern(ref_services, KRB5_CONF_ASTERISK))
- goto cleanup;
- } else
+ if (!in_list(hostbased, stype) && !in_list(hostbased, "*"))
goto cleanup;
/* FALLTHROUGH */
case KRB5_NT_SRV_HST:
case KRB5_NT_SRV_INST:
/* Deny referrals for specific service types, if configured. */
- if (kdc_active_realm->realm_no_host_referral != NULL) {
- if (krb5_match_config_pattern(nonref_services, stype))
- goto cleanup;
- if (krb5_match_config_pattern(nonref_services, KRB5_CONF_ASTERISK))
- goto cleanup;
- }
+ if (in_list(no_referral, stype) || in_list(no_referral, "*"))
+ goto cleanup;
ret = TRUE;
break;
default:
diff --git a/src/kdc/main.c b/src/kdc/main.c
index 51792fbccf..a5605f8c49 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -151,10 +151,10 @@ finish_realm(kdc_realm_t *rdp)
free(rdp->realm_tcp_ports);
if (rdp->realm_keytab)
krb5_kt_close(rdp->realm_context, rdp->realm_keytab);
- if (rdp->realm_host_based_services)
- free(rdp->realm_host_based_services);
- if (rdp->realm_no_host_referral)
- free(rdp->realm_no_host_referral);
+ if (rdp->realm_hostbased)
+ free(rdp->realm_hostbased);
+ if (rdp->realm_no_referral)
+ free(rdp->realm_no_referral);
if (rdp->realm_context) {
if (rdp->realm_mprinc)
krb5_free_principal(rdp->realm_context, rdp->realm_mprinc);
@@ -172,75 +172,24 @@ finish_realm(kdc_realm_t *rdp)
free(rdp);
}
+/* Set *val_out to an allocated string containing val1 and/or val2, separated
+ * by a space if both are set, or NULL if neither is set. */
static krb5_error_code
-handle_referral_params(krb5_realm_params *rparams,
- char *no_refrls, char *host_based_srvcs,
- kdc_realm_t *rdp )
+combine(const char *val1, const char *val2, char **val_out)
{
- krb5_error_code retval = 0;
- if (no_refrls && krb5_match_config_pattern(no_refrls, KRB5_CONF_ASTERISK) == TRUE) {
- rdp->realm_no_host_referral = strdup(KRB5_CONF_ASTERISK);
- if (!rdp->realm_no_host_referral)
- retval = ENOMEM;
- } else {
- if (rparams && rparams->realm_no_host_referral) {
- if (krb5_match_config_pattern(rparams->realm_no_host_referral,
- KRB5_CONF_ASTERISK) == TRUE) {
- rdp->realm_no_host_referral = strdup(KRB5_CONF_ASTERISK);
- if (!rdp->realm_no_host_referral)
- retval = ENOMEM;
- } else if (no_refrls) {
- if (asprintf(&(rdp->realm_no_host_referral),
- "%s%s%s%s%s", " ", no_refrls," ",
- rparams->realm_no_host_referral, " ") < 0)
- retval = ENOMEM;
- } else if (asprintf(&(rdp->realm_no_host_referral),"%s%s%s", " ",
- rparams->realm_no_host_referral, " ") < 0)
- retval = ENOMEM;
- } else if( no_refrls != NULL) {
- if ( asprintf(&(rdp->realm_no_host_referral),
- "%s%s%s", " ", no_refrls, " ") < 0)
- retval = ENOMEM;
- } else
- rdp->realm_no_host_referral = NULL;
- }
-
- if (rdp->realm_no_host_referral &&
- krb5_match_config_pattern(rdp->realm_no_host_referral,
- KRB5_CONF_ASTERISK) == TRUE) {
- rdp->realm_host_based_services = NULL;
- return 0;
- }
-
- if (host_based_srvcs &&
- (krb5_match_config_pattern(host_based_srvcs, KRB5_CONF_ASTERISK) == TRUE)) {
- rdp->realm_host_based_services = strdup(KRB5_CONF_ASTERISK);
- if (!rdp->realm_host_based_services)
- retval = ENOMEM;
+ if (val1 == NULL && val2 == NULL) {
+ *val_out = NULL;
+ } else if (val1 != NULL && val2 != NULL) {
+ if (asprintf(val_out, "%s %s", val1, val2) < 0) {
+ *val_out = NULL;
+ return ENOMEM;
+ }
} else {
- if (rparams && rparams->realm_host_based_services) {
- if (krb5_match_config_pattern(rparams->realm_host_based_services,
- KRB5_CONF_ASTERISK) == TRUE) {
- rdp->realm_host_based_services = strdup(KRB5_CONF_ASTERISK);
- if (!rdp->realm_host_based_services)
- retval = ENOMEM;
- } else if (host_based_srvcs) {
- if (asprintf(&(rdp->realm_host_based_services), "%s%s%s%s%s",
- " ", host_based_srvcs," ",
- rparams->realm_host_based_services, " ") < 0)
- retval = ENOMEM;
- } else if (asprintf(&(rdp->realm_host_based_services),"%s%s%s", " ",
- rparams->realm_host_based_services, " ") < 0)
- retval = ENOMEM;
- } else if (host_based_srvcs) {
- if (asprintf(&(rdp->realm_host_based_services),"%s%s%s", " ",
- host_based_srvcs, " ") < 0)
- retval = ENOMEM;
- } else
- rdp->realm_host_based_services = NULL;
+ *val_out = strdup((val1 != NULL) ? val1 : val2);
+ if (*val_out == NULL)
+ return ENOMEM;
}
-
- return retval;
+ return 0;
}
/*
@@ -254,7 +203,7 @@ static krb5_error_code
init_realm(kdc_realm_t *rdp, char *realm, char *def_mpname,
krb5_enctype def_enctype, char *def_udp_ports, char *def_tcp_ports,
krb5_boolean def_manual, krb5_boolean def_restrict_anon,
- char **db_args, char *no_refrls, char *host_based_srvcs)
+ char **db_args, char *no_referral, char *hostbased)
{
krb5_error_code kret;
krb5_boolean manual;
@@ -368,8 +317,13 @@ init_realm(kdc_realm_t *rdp, char *realm, char *def_mpname,
rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE;
/* Handle KDC referrals */
- kret = handle_referral_params(rparams, no_refrls, host_based_srvcs, rdp);
- if (kret == ENOMEM)
+ kret = combine(no_referral, rparams->realm_no_referral,
+ &rdp->realm_no_referral);
+ if (kret)
+ goto whoops;
+
+ kret = combine(hostbased, rparams->realm_hostbased, &rdp->realm_hostbased);
+ if (kret)
goto whoops;
if (rparams)
@@ -673,8 +627,8 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
char *default_tcp_ports = 0;
krb5_pointer aprof;
const char *hierarchy[3];
- char *no_refrls = NULL;
- char *host_based_srvcs = NULL;
+ char *no_referral = NULL;
+ char *hostbased = NULL;
int db_args_size = 0;
char **db_args = NULL;
@@ -696,14 +650,11 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &def_restrict_anon))
def_restrict_anon = FALSE;
hierarchy[1] = KRB5_CONF_NO_HOST_REFERRAL;
- if (krb5_aprof_get_string_all(aprof, hierarchy, &no_refrls))
- no_refrls = 0;
- if (!no_refrls ||
- krb5_match_config_pattern(no_refrls, KRB5_CONF_ASTERISK) == FALSE) {
- hierarchy[1] = KRB5_CONF_HOST_BASED_SERVICES;
- if (krb5_aprof_get_string_all(aprof, hierarchy, &host_based_srvcs))
- host_based_srvcs = 0;
- }
+ if (krb5_aprof_get_string_all(aprof, hierarchy, &no_referral))
+ no_referral = 0;
+ hierarchy[1] = KRB5_CONF_HOST_BASED_SERVICES;
+ if (krb5_aprof_get_string_all(aprof, hierarchy, &hostbased))
+ hostbased = 0;
krb5_aprof_finish(aprof);
}
@@ -753,7 +704,7 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
menctype, default_udp_ports,
default_tcp_ports, manual,
def_restrict_anon, db_args,
- no_refrls, host_based_srvcs))) {
+ no_referral, hostbased))) {
fprintf(stderr, _("%s: cannot initialize realm %s - "
"see log file for details\n"),
argv[0], optarg);
@@ -869,7 +820,7 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
if ((retval = init_realm(rdatap, lrealm, mkey_name, menctype,
default_udp_ports, default_tcp_ports,
manual, def_restrict_anon, db_args,
- no_refrls, host_based_srvcs))) {
+ no_referral, hostbased))) {
fprintf(stderr, _("%s: cannot initialize realm %s - see log "
"file for details\n"), argv[0], lrealm);
exit(1);
@@ -888,10 +839,10 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
free(db_args);
if (db_name)
free(db_name);
- if (host_based_srvcs)
- free(host_based_srvcs);
- if (no_refrls)
- free(no_refrls);
+ if (hostbased)
+ free(hostbased);
+ if (no_referral)
+ free(no_referral);
return;
}
diff --git a/src/kdc/realm_data.h b/src/kdc/realm_data.h
index 0387c28ae6..1593c442e5 100644
--- a/src/kdc/realm_data.h
+++ b/src/kdc/realm_data.h
@@ -45,11 +45,8 @@ typedef struct __kdc_realm_data {
krb5_context realm_context; /* Context to be used for realm */
krb5_keytab realm_keytab; /* keytab to be used for this realm */
char * realm_profile; /* Profile file for this realm */
- char * realm_host_based_services; /* do referral processing for these services
- * If '*' - allow all referrals */
- char * realm_no_host_referral; /* no referral for these services.
- * If '*' - disallow all referrals and
- * ignore realm_host_based_services */
+ char * realm_hostbased; /* referral services for NT-UNKNOWN */
+ char * realm_no_referral; /* non-referral services */
/*
* Database per-realm data.
*/