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