use getaddrinfo instead of dns_lookup when testing for
kerberos.REALM. this allows reusing that information when actually contacting the server and thus avoids one DNS lookup git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@10149 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		@@ -238,6 +238,26 @@ krb5_krbhst_format_string(krb5_context context, const krb5_krbhst_info *host,
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * create a getaddrinfo `hints' based on 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					make_hints(struct addrinfo *hints, int proto)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memset(hints, 0, sizeof(*hints));
 | 
				
			||||||
 | 
					    hints->ai_family = AF_UNSPEC;
 | 
				
			||||||
 | 
					    switch(proto) {
 | 
				
			||||||
 | 
					    case KRB5_KRBHST_UDP :
 | 
				
			||||||
 | 
						hints->ai_socktype = SOCK_DGRAM;
 | 
				
			||||||
 | 
						break;
 | 
				
			||||||
 | 
					    case KRB5_KRBHST_HTTP :
 | 
				
			||||||
 | 
					    case KRB5_KRBHST_TCP :
 | 
				
			||||||
 | 
						hints->ai_socktype = SOCK_STREAM;
 | 
				
			||||||
 | 
						break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * return an `struct addrinfo *' in `ai' corresponding to the information
 | 
					 * return an `struct addrinfo *' in `ai' corresponding to the information
 | 
				
			||||||
 * in `host'.  free:ing is handled by krb5_krbhst_free.
 | 
					 * in `host'.  free:ing is handled by krb5_krbhst_free.
 | 
				
			||||||
@@ -252,17 +272,7 @@ krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
 | 
				
			|||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (host->ai == NULL) {
 | 
					    if (host->ai == NULL) {
 | 
				
			||||||
	memset (&hints, 0, sizeof(hints));
 | 
						make_hints(&hints, host->proto);
 | 
				
			||||||
	hints.ai_family = AF_UNSPEC;
 | 
					 | 
				
			||||||
	switch(host->proto) {
 | 
					 | 
				
			||||||
	case KRB5_KRBHST_UDP :
 | 
					 | 
				
			||||||
	    hints.ai_socktype = SOCK_DGRAM;
 | 
					 | 
				
			||||||
	    break;
 | 
					 | 
				
			||||||
	case KRB5_KRBHST_HTTP :
 | 
					 | 
				
			||||||
	case KRB5_KRBHST_TCP :
 | 
					 | 
				
			||||||
	    hints.ai_socktype = SOCK_STREAM;
 | 
					 | 
				
			||||||
	    break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	snprintf (portstr, sizeof(portstr), "%d", host->port);
 | 
						snprintf (portstr, sizeof(portstr), "%d", host->port);
 | 
				
			||||||
	ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
 | 
						ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
@@ -317,12 +327,22 @@ config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
 | 
				
			|||||||
    krb5_config_free_strings(hostlist);
 | 
					    krb5_config_free_strings(hostlist);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					/*
 | 
				
			||||||
 | 
					 * as a fallback, look for `serv_string.kd->realm' (typically
 | 
				
			||||||
 | 
					 * kerberos.REALM, kerberos-1.REALM, ...
 | 
				
			||||||
 | 
					 * `def_port' is the default port for the service, and `proto' the 
 | 
				
			||||||
 | 
					 * protocol
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static krb5_error_code
 | 
				
			||||||
fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, 
 | 
					fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, 
 | 
				
			||||||
		   const char *serv_string, int def_port)
 | 
							   const char *serv_string, int def_port, int proto)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *host;
 | 
					    char *host;
 | 
				
			||||||
    struct dns_reply *r;
 | 
					    int ret;
 | 
				
			||||||
 | 
					    struct addrinfo *ai;
 | 
				
			||||||
 | 
					    struct addrinfo hints;
 | 
				
			||||||
 | 
					    char portstr[NI_MAXSERV];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(kd->fallback_count == 0)
 | 
					    if(kd->fallback_count == 0)
 | 
				
			||||||
	asprintf(&host, "%s.%s.", serv_string, kd->realm);
 | 
						asprintf(&host, "%s.%s.", serv_string, kd->realm);
 | 
				
			||||||
@@ -330,18 +350,34 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
 | 
				
			|||||||
	asprintf(&host, "%s-%d.%s.", 
 | 
						asprintf(&host, "%s-%d.%s.", 
 | 
				
			||||||
		 serv_string, kd->fallback_count, kd->realm);	    
 | 
							 serv_string, kd->fallback_count, kd->realm);	    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    r = dns_lookup(host, "A");
 | 
					    if (host == NULL)
 | 
				
			||||||
    if(r == NULL)
 | 
						return ENOMEM;
 | 
				
			||||||
	r = dns_lookup(host, "CNAME");
 | 
					    
 | 
				
			||||||
    if(r == NULL) {
 | 
					    make_hints(&hints, proto);
 | 
				
			||||||
 | 
					    snprintf(portstr, sizeof(portstr), "%d", def_port);
 | 
				
			||||||
 | 
					    ret = getaddrinfo(host, portstr, &hints, &ai);
 | 
				
			||||||
 | 
					    if (ret) {
 | 
				
			||||||
	/* no more hosts, so we're done here */
 | 
						/* no more hosts, so we're done here */
 | 
				
			||||||
	free(host);
 | 
						free(host);
 | 
				
			||||||
	kd->flags |= KD_FALLBACK;
 | 
						kd->flags |= KD_FALLBACK;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
	host[strlen(host) - 1] = '\0';
 | 
						struct krb5_krbhst_info *hi;
 | 
				
			||||||
	append_host_string(context, kd, host, def_port);
 | 
					
 | 
				
			||||||
 | 
						hi = calloc(1, sizeof(*hi) + strlen(host));
 | 
				
			||||||
 | 
						if(hi == NULL) {
 | 
				
			||||||
 | 
						    free(host);
 | 
				
			||||||
 | 
						    return ENOMEM;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hi->proto = proto;
 | 
				
			||||||
 | 
						hi->port  = hi->def_port = def_port;
 | 
				
			||||||
 | 
						hi->ai    = ai;
 | 
				
			||||||
 | 
						strcpy(hi->hostname, host);
 | 
				
			||||||
 | 
						free(host);
 | 
				
			||||||
 | 
						append_host_hostinfo(kd, hi);
 | 
				
			||||||
	kd->fallback_count++;
 | 
						kd->fallback_count++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static krb5_error_code
 | 
					static krb5_error_code
 | 
				
			||||||
@@ -349,6 +385,7 @@ kdc_get_next(krb5_context context,
 | 
				
			|||||||
	     struct krb5_krbhst_data *kd,
 | 
						     struct krb5_krbhst_data *kd,
 | 
				
			||||||
	     krb5_krbhst_info **host)
 | 
						     krb5_krbhst_info **host)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    krb5_error_code ret;
 | 
				
			||||||
    int port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
 | 
					    int port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if((kd->flags & KD_CONFIG) == 0) {
 | 
					    if((kd->flags & KD_CONFIG) == 0) {
 | 
				
			||||||
@@ -384,7 +421,10 @@ kdc_get_next(krb5_context context,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while((kd->flags & KD_FALLBACK) == 0) {
 | 
					    while((kd->flags & KD_FALLBACK) == 0) {
 | 
				
			||||||
	fallback_get_hosts(context, kd, "kerberos", port);
 | 
						ret = fallback_get_hosts(context, kd, "kerberos",
 | 
				
			||||||
 | 
									 port, KRB5_KRBHST_UDP);
 | 
				
			||||||
 | 
						if(ret)
 | 
				
			||||||
 | 
						    return ret;
 | 
				
			||||||
	if(get_next(kd, host))
 | 
						if(get_next(kd, host))
 | 
				
			||||||
	    return 0;
 | 
						    return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -397,6 +437,7 @@ admin_get_next(krb5_context context,
 | 
				
			|||||||
	       struct krb5_krbhst_data *kd,
 | 
						       struct krb5_krbhst_data *kd,
 | 
				
			||||||
	       krb5_krbhst_info **host)
 | 
						       krb5_krbhst_info **host)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    krb5_error_code ret;
 | 
				
			||||||
    int port = ntohs(krb5_getportbyname (context, "kerberos-adm", "tcp", 749));
 | 
					    int port = ntohs(krb5_getportbyname (context, "kerberos-adm", "tcp", 749));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if((kd->flags & KD_CONFIG) == 0) {
 | 
					    if((kd->flags & KD_CONFIG) == 0) {
 | 
				
			||||||
@@ -420,7 +461,10 @@ admin_get_next(krb5_context context,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (krbhst_empty(kd)
 | 
					    if (krbhst_empty(kd)
 | 
				
			||||||
	&& (kd->flags & KD_FALLBACK) == 0) {
 | 
						&& (kd->flags & KD_FALLBACK) == 0) {
 | 
				
			||||||
	fallback_get_hosts(context, kd, "kerberos", port);
 | 
						ret = fallback_get_hosts(context, kd, "kerberos",
 | 
				
			||||||
 | 
									 port, KRB5_KRBHST_UDP);
 | 
				
			||||||
 | 
						if(ret)
 | 
				
			||||||
 | 
						    return ret;
 | 
				
			||||||
	kd->flags |= KD_FALLBACK;
 | 
						kd->flags |= KD_FALLBACK;
 | 
				
			||||||
	if(get_next(kd, host))
 | 
						if(get_next(kd, host))
 | 
				
			||||||
	    return 0;
 | 
						    return 0;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user