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.
{
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;
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:
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);
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;
}
/*
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;
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)
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;
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);
}
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);
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);
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;
}
#include <ctype.h>
#include <kdb_log.h>
-krb5_boolean krb5_match_config_pattern(const char *, const char*);
static krb5_key_salt_tuple *copy_key_salt_tuple(ksalt, len)
krb5_key_salt_tuple *ksalt;
krb5_int32 len;
char *kdcprofile = 0;
char *kdcenv = 0;
- char *no_refrls = 0;
- char *host_based_srvcs = 0;
-
-
-
- krb5_error_code kret;
+ char *no_referral = 0;
+ char *hostbased = 0;
+ krb5_error_code kret;
filename = (kdcprofile) ? kdcprofile : DEFAULT_KDC_PROFILE;
envname = (kdcenv) ? kdcenv : KDC_PROFILE_ENV;
}
hierarchy[2] = KRB5_CONF_NO_HOST_REFERRAL;
- if (!krb5_aprof_get_string_all(aprofile, hierarchy, &no_refrls))
- rparams->realm_no_host_referral = no_refrls;
- else
- no_refrls = 0;
-
- if (!no_refrls || krb5_match_config_pattern(no_refrls, KRB5_CONF_ASTERISK) == FALSE) {
- hierarchy[2] = KRB5_CONF_HOST_BASED_SERVICES;
- if (!krb5_aprof_get_string_all(aprofile, hierarchy, &host_based_srvcs))
- rparams->realm_host_based_services = host_based_srvcs;
- else
- host_based_srvcs = 0;
- }
+ if (!krb5_aprof_get_string_all(aprofile, hierarchy, &no_referral))
+ rparams->realm_no_referral = no_referral;
+
+ hierarchy[2] = KRB5_CONF_HOST_BASED_SERVICES;
+ if (!krb5_aprof_get_string_all(aprofile, hierarchy, &hostbased))
+ rparams->realm_hostbased = hostbased;
/* Get the value for the default principal flags */
hierarchy[2] = KRB5_CONF_DEFAULT_PRINCIPAL_FLAGS;
free(rparams->realm_kdc_ports);
free(rparams->realm_kdc_tcp_ports);
free(rparams->realm_acl_file);
- free(rparams->realm_no_host_referral);
- free(rparams->realm_host_based_services);
+ free(rparams->realm_no_referral);
+ free(rparams->realm_hostbased);
free(rparams);
}
return(0);
}
-/*
- * match_config_pattern -
- * returns TRUE is the pattern is found in the attr's list of values.
- * Otherwise - FALSE.
- * In conf file the values are separates by commas or whitespaces.
- */
-krb5_boolean
-krb5_match_config_pattern(const char *string, const char *pattern)
-{
- const char *ptr;
- char next = '\0';
- int len = strlen(pattern);
-
- for (ptr = strstr(string,pattern); ptr != 0; ptr = strstr(ptr+len,pattern)) {
- if (ptr == string
- || isspace((unsigned char)*(ptr-1))
- || *(ptr-1) ==',') {
- next = *(ptr + len);
- if (next == '\0' || isspace((unsigned char)next) || next ==',') {
- return TRUE;
- }
- }
- }
- return FALSE;
-}