Ejemplo n.º 1
0
krb5_error_code KRB5_CALLCONV
krb5_get_default_realm(krb5_context context, char **lrealm)
{
    char *realm = 0;
    char *cp;
    char localhost[MAX_DNS_NAMELEN+1];
    krb5_error_code retval;

    (void) memset(localhost, 0, sizeof(localhost));

    if (!context || (context->magic != KV5M_CONTEXT)) 
	    return KV5M_CONTEXT;

    /*
     * Solaris Kerberos: (illumos)
     * Another way to provide the default realm.
     */
    if (!context->default_realm) {
	if ((realm = getenv("KRB5_DEFAULT_REALM")) != NULL) {
	    context->default_realm = strdup(realm);
	    if (context->default_realm == NULL)
		return ENOMEM;
	}
    }

    if (!context->default_realm) {
        context->default_realm = 0;
        if (context->profile != 0) {
            retval = profile_get_string(context->profile, "libdefaults",
                                        "default_realm", 0, 0,
                                        &realm);

            if (!retval && realm) {
                context->default_realm = malloc(strlen(realm) + 1);
                if (!context->default_realm) {
                    profile_release_string(realm);
                    return ENOMEM;
                }
                strcpy(context->default_realm, realm);
                profile_release_string(realm);
            }
        }
        if (context->default_realm == 0) {
#ifdef KRB5_DNS_LOOKUP
            if (_krb5_use_dns_realm(context)) {
		/*
		 * Since this didn't appear in our config file, try looking
		 * it up via DNS.  Look for a TXT records of the form:
		 *
		 * _kerberos.<localhost>
		 * _kerberos.<domainname>
		 * _kerberos.<searchlist>
		 *
		 */
		char * p;
		krb5int_get_fq_local_hostname (localhost, sizeof(localhost));

		if ( localhost[0] ) {
		    p = localhost;
		    do {
			retval = krb5_try_realm_txt_rr("_kerberos", p, 
						       &context->default_realm);
			p = strchr(p,'.');
			if (p)
			    p++;
		    } while (retval && p && p[0]);

		    if (retval)
			retval = krb5_try_realm_txt_rr("_kerberos", "", 
						       &context->default_realm);
		} else {
		    retval = krb5_try_realm_txt_rr("_kerberos", "", 
						   &context->default_realm);
		}
		if (retval) {
		    return(KRB5_CONFIG_NODEFREALM);
		}
            } else
#endif /* KRB5_DNS_LOOKUP */
            if (getenv("MS_INTEROP") == NULL) {

	/*
	 * Solaris Kerberos:
	 * Try to find a realm based on one of the local IP addresses.
	 * Don't do this for AD, which often does _not_ support any
	 * DNS reverse lookup, making these queries take forever.
	 */
	(void) krb5int_foreach_localaddr(context,
	    krb5int_address_get_realm, 0, 0);

	/*
	 * Solaris Kerberos:
	 * As a final fallback try to find a realm based on the resolver search
	 * list
	 */
	if (context->default_realm == 0) {
		struct __res_state res;
		int i;

		(void) memset(&res, 0, sizeof (res));

		if (res_ninit(&res) == 0) {
			for (i = 0; res.dnsrch[i]; i++) {
				krb5int_domain_get_realm(context,
				    res.dnsrch[i], &context->default_realm); 

				if (context->default_realm != 0)
					break;
			}
		res_ndestroy(&res);
		}
	}

	}
	}
	}

    if (context->default_realm == 0)
	return(KRB5_CONFIG_NODEFREALM);
    if (context->default_realm[0] == 0) {
        free (context->default_realm);
        context->default_realm = 0;
        return KRB5_CONFIG_NODEFREALM;
    }

    realm = context->default_realm;
    
    /*LINTED*/
    if (!(*lrealm = cp = malloc((unsigned int) strlen(realm) + 1)))
        return ENOMEM;
    strcpy(cp, realm);
    return(0);
}
Ejemplo n.º 2
0
krb5_error_code KRB5_CALLCONV
krb5_get_fallback_host_realm(krb5_context context, krb5_data *hdata, char ***realmsp)
{
    char **retrealms;
    char *realm, *cp;
    krb5_error_code retval;
    char local_host[MAXDNAME+1], host[MAXDNAME+1];

    /* Convert what we hope is a hostname to a string. */
    memcpy(host, hdata->data, hdata->length);
    host[hdata->length]=0;

#ifdef DEBUG_REFERRALS
    printf("get_fallback_host_realm(host >%s<) called\n",host);
#endif

    retval = krb5int_clean_hostname(context, host, local_host, sizeof local_host);
    if (retval)
        return retval;

    /*
     * Try looking up a _kerberos.<hostname> TXT record in DNS.  This
     * heuristic is turned off by default since, in the absence of
     * secure DNS, it can allow an attacker to control the realm used
     * for a host.
     */
    realm = (char *)NULL;
#ifdef KRB5_DNS_LOOKUP
    if (_krb5_use_dns_realm(context)) {
	cp = local_host;
	do {
	    retval = krb5_try_realm_txt_rr("_kerberos", cp, &realm);
	    cp = strchr(cp,'.');
	    if (cp) 
		cp++;
	} while (retval && cp && cp[0]);
    }
#endif /* KRB5_DNS_LOOKUP */

    /*
     * Next try searching the domain components as realms.  This
     * heuristic is also turned off by default.  If DNS lookups for
     * KDCs are enabled (as they are by default), an attacker could
     * control which domain component is used as the realm for a host.
     */
    if (realm == (char *)NULL) {
	int limit;
	errcode_t code;

	code = profile_get_integer(context->profile, KRB5_CONF_LIBDEFAULTS,
				   KRB5_CONF_REALM_TRY_DOMAINS, 0, -1, &limit);
	if (code == 0) {
	    retval = domain_heuristic(context, local_host, &realm, limit);
	    if (retval)
		return retval;
	}
    }

    /*
     * The next fallback--and the first one to apply with default
     * configuration--is to use the upper-cased parent domain of the
     * hostname, regardless of whether we can actually look it up as a
     * realm.
     */
    if (realm == (char *)NULL) {
	cp = strchr(local_host, '.');
	if (cp) {
	    if (!(realm = strdup(cp + 1)))
		return ENOMEM;
            for (cp = realm; *cp; cp++)
                if (islower((int) (*cp)))
                    *cp = toupper((int) *cp);
	}
    }

    /*
     * The final fallback--used when the fully-qualified hostname has
     * only one component--is to use the local default realm.
     */
    if (realm == (char *)NULL) {
	retval = krb5_get_default_realm(context, &realm);
	if (retval)
	    return retval;
    }

    if (!(retrealms = (char **)calloc(2, sizeof(*retrealms)))) {
	if (realm != (char *)NULL)
	    free(realm);
	return ENOMEM;
    }

    retrealms[0] = realm;
    retrealms[1] = 0;
    
    *realmsp = retrealms;
    return 0;
}
Ejemplo n.º 3
0
krb5_error_code KRB5_CALLCONV
krb5_get_default_realm(krb5_context context, char **lrealm)
{
    char *realm = 0;
    krb5_error_code retval;

    if (!context || (context->magic != KV5M_CONTEXT))
        return KV5M_CONTEXT;

    if (!context->default_realm) {
        /*
         * XXX should try to figure out a reasonable default based
         * on the host's DNS domain.
         */
        context->default_realm = 0;
        if (context->profile != 0) {
            retval = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
                                        KRB5_CONF_DEFAULT_REALM, 0, 0,
                                        &realm);

            if (!retval && realm) {
                context->default_realm = strdup(realm);
                if (!context->default_realm) {
                    profile_release_string(realm);
                    return ENOMEM;
                }
                profile_release_string(realm);
            }
        }
#ifndef KRB5_DNS_LOOKUP
        else
            return KRB5_CONFIG_CANTOPEN;
#else /* KRB5_DNS_LOOKUP */
        if (context->default_realm == 0) {
            int use_dns =  _krb5_use_dns_realm(context);
            if ( use_dns ) {
                /*
                 * Since this didn't appear in our config file, try looking
                 * it up via DNS.  Look for a TXT records of the form:
                 *
                 * _kerberos.<localhost>
                 * _kerberos.<domainname>
                 * _kerberos.<searchlist>
                 *
                 */
                char localhost[MAX_DNS_NAMELEN+1];
                char * p;

                krb5int_get_fq_local_hostname (localhost, sizeof(localhost));

                if ( localhost[0] ) {
                    p = localhost;
                    do {
                        retval = krb5_try_realm_txt_rr("_kerberos", p,
                                                       &context->default_realm);
                        p = strchr(p,'.');
                        if (p)
                            p++;
                    } while (retval && p && p[0]);

                    if (retval)
                        retval = krb5_try_realm_txt_rr("_kerberos", "",
                                                       &context->default_realm);
                } else {
                    retval = krb5_try_realm_txt_rr("_kerberos", "",
                                                   &context->default_realm);
                }
                if (retval) {
                    return(KRB5_CONFIG_NODEFREALM);
                }
            }
        }
#endif /* KRB5_DNS_LOOKUP */
    }

    if (context->default_realm == 0)
        return(KRB5_CONFIG_NODEFREALM);
    if (context->default_realm[0] == 0) {
        free (context->default_realm);
        context->default_realm = 0;
        return KRB5_CONFIG_NODEFREALM;
    }

    realm = context->default_realm;

    if (!(*lrealm = strdup(realm)))
        return ENOMEM;
    return(0);
}