diff options
author | Ken Raeburn <raeburn@mit.edu> | 2002-06-04 06:59:28 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@mit.edu> | 2002-06-04 06:59:28 +0000 |
commit | b02232ffdf69f75caaf10c78e00a9fa8f93b3286 (patch) | |
tree | 8324d8d24db2a4b72d95cfe57c7762355e5edd81 /src/lib | |
parent | 53c8f6650caef85bb9b38f23e0e50965d50d26f6 (diff) | |
download | krb5-b02232ffdf69f75caaf10c78e00a9fa8f93b3286.tar.gz krb5-b02232ffdf69f75caaf10c78e00a9fa8f93b3286.tar.xz krb5-b02232ffdf69f75caaf10c78e00a9fa8f93b3286.zip |
Add capability of looking up TCP addresses for KDC in DNS; not enabled yet.
Internal "addrlist" structure now includes socket type, by way of using
struct addrinfo where struct sockaddr was used before; updated uses.
No support for noting TCP/UDP vs UDP-only addresses in config files.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14465 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/krb5/os/ChangeLog | 26 | ||||
-rw-r--r-- | src/lib/krb5/os/changepw.c | 13 | ||||
-rw-r--r-- | src/lib/krb5/os/locate_kdc.c | 152 | ||||
-rw-r--r-- | src/lib/krb5/os/sendto_kdc.c | 19 | ||||
-rw-r--r-- | src/lib/krb5/os/t_locate_kdc.c | 23 |
5 files changed, 133 insertions, 100 deletions
diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index 9f981c884a..9f75d40b93 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,29 @@ +2002-06-04 Ken Raeburn <raeburn@mit.edu> + + * locate_kdc.c: Include fake-addrinfo.h before k5-int.h. + (grow_list, krb5int_free_addrlist) + (add_addrinfo_to_list): Incorporate list-updating code from + add_sockaddr_to_list. Store an addrinfo pointer, and set the + ai_next field to null. + (add_host_to_list): New arg SOCKTYPE. Write port numbers into + buffers and let getaddrinfo fill in the sin*_port fields. Call + getaddrinfo twice, and use two loops to add entries to the + addrlist structure. + (add_sockaddr_to_list, set_port_num): Deleted. + (krb5_locate_srv_conf_1, krb5_locate_srv_dns_1): Pass extra arg + to add_host_to_list. + (krb5int_locate_server): New value 2 for is_stream arg means + accept both UDP and TCP. + * changepw.c: Include fake-addrinfo.h. + (krb5_locate_passwd, krb5_change_password): Update for addrlist + changes. + * sendto_kdc.c: Include fake-addrinfo.h. + (krb5_sendto_kdc): Update for addrlist changes. Skip any + addresses that are not SOCK_DGRAM. + * t_locate_kdc.c (stypename): New function. + (print_addrs): Update for addrlist changes. Print socket type + with address and port. + 2002-04-12 Ken Raeburn <raeburn@mit.edu> * lock_file.c (krb5_lock_file) [POSIX_FILE_LOCKS]: Make static diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c index 88d50cc907..42b77286e2 100644 --- a/src/lib/krb5/os/changepw.c +++ b/src/lib/krb5/os/changepw.c @@ -26,6 +26,7 @@ */ #define NEED_SOCKETS +#include "fake-addrinfo.h" #include "k5-int.h" #include "os-proto.h" #include "adm_err.h" @@ -75,9 +76,9 @@ krb5_locate_kpasswd(krb5_context context, const krb5_data *realm, port number to use DEFAULT_KPASSWD_PORT. */ int i; for ( i=0;i<addrlist->naddrs;i++ ) { - struct sockaddr *a = addrlist->addrs[i]; - if (a->sa_family == AF_INET) - sa2sin (a)->sin_port = htons(DEFAULT_KPASSWD_PORT); + struct addrinfo *a = addrlist->addrs[i]; + if (a->ai_family == AF_INET) + sa2sin (a->ai_addr)->sin_port = htons(DEFAULT_KPASSWD_PORT); } } } @@ -169,11 +170,11 @@ krb5_change_password(context, creds, newpw, result_code, struct timeval timeout; /* XXX Now the locate_ functions can return IPv6 addresses. */ - if (al.addrs[i]->sa_family != AF_INET) + if (al.addrs[i]->ai_family != AF_INET) continue; tried_one = 1; - if (connect(s2, al.addrs[i], socklen(al.addrs[i])) == SOCKET_ERROR) { + if (connect(s2, al.addrs[i]->ai_addr, al.addrs[i]->ai_addrlen) == SOCKET_ERROR) { if (SOCKET_ERRNO == ECONNREFUSED || SOCKET_ERRNO == EHOSTUNREACH) continue; /* try the next addr */ @@ -254,7 +255,7 @@ krb5_change_password(context, creds, newpw, result_code, if ((cc = sendto(s1, chpw_req.data, (GETSOCKNAME_ARG3_TYPE) chpw_req.length, 0, - al.addrs[i], socklen(al.addrs[i]))) != chpw_req.length) + al.addrs[i]->ai_addr, al.addrs[i]->ai_addrlen)) != chpw_req.length) { if ((cc < 0) && ((SOCKET_ERRNO == ECONNREFUSED) || (SOCKET_ERRNO == EHOSTUNREACH))) diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c index cc6d9c5670..d1819939d1 100644 --- a/src/lib/krb5/os/locate_kdc.c +++ b/src/lib/krb5/os/locate_kdc.c @@ -28,6 +28,7 @@ */ #define NEED_SOCKETS +#include "fake-addrinfo.h" #include "k5-int.h" #include "os-proto.h" #include <stdio.h> @@ -44,8 +45,6 @@ #define T_SRV 33 #endif /* T_SRV */ -#include "fake-addrinfo.h" - /* for old Unixes and friends ... */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 @@ -133,7 +132,7 @@ grow_list (struct addrlist *lp, int nmore) int i; int newspace = lp->space + nmore; size_t newsize = newspace * sizeof (struct addrlist); - struct sockaddr **newaddrs; + struct addrinfo **newaddrs; /* NULL check a concession to SunOS4 compatibility for now; not required for pure ANSI support. */ @@ -158,57 +157,13 @@ krb5int_free_addrlist (struct addrlist *lp) { int i; for (i = 0; i < lp->naddrs; i++) - free (lp->addrs[i]); + freeaddrinfo (lp->addrs[i]); free (lp->addrs); lp->addrs = NULL; lp->naddrs = lp->space = 0; } #define free_list krb5int_free_addrlist -static int -add_sockaddr_to_list (struct addrlist *lp, const struct sockaddr *addr, - size_t len) -{ - struct sockaddr *copy; - int err; - -#ifdef TEST - char name[NI_MAXHOST]; - - fprintf (stderr, "\tadding sockaddr family %2d, len %d", addr->sa_family, - len); - - err = getnameinfo (addr, len, name, sizeof (name), NULL, 0, - NI_NUMERICHOST | NI_NUMERICSERV); - if (err == 0) - fprintf (stderr, "\t%s", name); - fprintf (stderr, "\n"); -#endif - - if (lp->naddrs == lp->space) { - err = grow_list (lp, 1); - if (err) { -#ifdef TEST - fprintf (stderr, "grow_list failed %d\n", err); -#endif - return err; - } - } - copy = malloc (len); - if (copy == NULL) { -#ifdef TEST - perror ("malloc"); -#endif - return errno; - } - memcpy (copy, addr, len); - lp->addrs[lp->naddrs++] = copy; -#ifdef TEST - fprintf (stderr, "count is now %d\n", lp->naddrs); -#endif - return 0; -} - static int translate_ai_error (int err) { switch (err) { @@ -249,8 +204,8 @@ static int translate_ai_error (int err) static int add_addrinfo_to_list (struct addrlist *lp, struct addrinfo *a) { - int r; - r = add_sockaddr_to_list (lp, a->ai_addr, a->ai_addrlen); + int err; + #ifdef TEST switch (a->ai_socktype) { case SOCK_DGRAM: @@ -269,29 +224,31 @@ static int add_addrinfo_to_list (struct addrlist *lp, struct addrinfo *a) break; } #endif - return r; -} -static void set_port_num (struct sockaddr *addr, int num) -{ - switch (addr->sa_family) { - case AF_INET: - ((struct sockaddr_in *)addr)->sin_port = num; - break; -#ifdef KRB5_USE_INET6 - case AF_INET6: - ((struct sockaddr_in6 *)addr)->sin6_port = num; - break; + if (lp->naddrs == lp->space) { + err = grow_list (lp, 1); + if (err) { +#ifdef TEST + fprintf (stderr, "grow_list failed %d\n", err); #endif + return err; + } } + lp->addrs[lp->naddrs++] = a; + a->ai_next = 0; +#ifdef TEST + fprintf (stderr, "count is now %d\n", lp->naddrs); +#endif + return 0; } static int add_host_to_list (struct addrlist *lp, const char *hostname, - int port, int secport) + int port, int secport, int socktype) { - struct addrinfo *addrs, *a, hint; + struct addrinfo *addrs, *a, *anext, hint; int err; + char portbuf[10], secportbuf[10]; #ifdef TEST fprintf (stderr, "adding hostname %s, ports %d,%d\n", hostname, @@ -299,25 +256,29 @@ add_host_to_list (struct addrlist *lp, const char *hostname, #endif memset(&hint, 0, sizeof(hint)); - hint.ai_socktype = SOCK_DGRAM; - err = getaddrinfo (hostname, NULL, &hint, &addrs); + hint.ai_socktype = socktype; + sprintf(portbuf, "%d", ntohs(port)); + sprintf(secportbuf, "%d", ntohs(secport)); + err = getaddrinfo (hostname, portbuf, &hint, &addrs); if (err) return translate_ai_error (err); - for (a = addrs; a; a = a->ai_next) { - set_port_num (a->ai_addr, port); + anext = 0; + for (a = addrs; a != 0 && err == 0; a = anext) { + anext = a->ai_next; err = add_addrinfo_to_list (lp, a); - if (err) - break; - - if (secport == 0) - continue; - - set_port_num (a->ai_addr, secport); + } + if (err || secport == 0) + goto egress; + err = getaddrinfo (hostname, secportbuf, &hint, &addrs); + if (err) + return translate_ai_error (err); + for (a = addrs; a != 0 && err == 0; a = anext) { + anext = a->ai_next; err = add_addrinfo_to_list (lp, a); - if (err) - break; } - freeaddrinfo (addrs); +egress: + if (anext) + freeaddrinfo (anext); return err; } @@ -470,7 +431,7 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm, p2 = sec_udpport; } - code = add_host_to_list (addrlist, hostlist[i], p1, p2); + code = add_host_to_list (addrlist, hostlist[i], p1, p2, SOCK_DGRAM); if (code) { #ifdef TEST fprintf (stderr, "error %d returned from add_host_to_list\n", code); @@ -732,7 +693,10 @@ krb5_locate_srv_dns_1 (const krb5_data *realm, #ifdef TEST fprintf (stderr, "\tport=%d host=%s\n", entry->port, entry->host); #endif - code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0); + code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0, + (strcmp("_tcp", protocol) + ? SOCK_DGRAM + : SOCK_STREAM)); if (code) break; } @@ -795,9 +759,31 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm, #ifdef KRB5_DNS_LOOKUP if (code && dnsname != 0) { int use_dns = _krb5_use_dns_kdc(context); - if (use_dns) - code = krb5_locate_srv_dns_1(realm, dnsname, - is_stream ? "_tcp" : "_udp", &al); + if (use_dns) { + /* Values of is_stream: + 0: udp only + 1: tcp only + 2: udp or tcp + No other values currently allowed. */ + code = 0; +#ifdef TEST + fprintf(stderr, "is_stream = %d\n", is_stream); +#endif + if (is_stream != 1) { + code = krb5_locate_srv_dns_1(realm, dnsname, "_udp", &al); +#ifdef TEST + if (code) + fprintf(stderr, "dns lookup returned error %d\n", code); +#endif + } + if (is_stream != 0 && code == 0) { + code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp", &al); +#ifdef TEST + if (code) + fprintf(stderr, "dns lookup returned error %d\n", code); +#endif + } + } } #endif /* KRB5_DNS_LOOKUP */ #ifdef TEST diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c index 7bb63522c3..595e2c9d8c 100644 --- a/src/lib/krb5/os/sendto_kdc.c +++ b/src/lib/krb5/os/sendto_kdc.c @@ -30,6 +30,7 @@ #define NEED_SOCKETS #define NEED_LOWLEVEL_IO +#include "fake-addrinfo.h" #include "k5-int.h" #ifdef HAVE_SYS_TIME_H @@ -120,9 +121,11 @@ krb5_sendto_kdc (context, message, realm, reply, use_master) timeout <<= krb5_skdc_timeout_shift) { sent = 0; for (host = 0; host < addrs.naddrs; host++) { - /* send to the host, wait timeout seconds for a response, + if (addrs.addrs[host]->ai_socktype != SOCK_DGRAM) + continue; + /* Send to the host, wait timeout seconds for a response, then move on. */ - /* cache some sockets for each host */ + /* Cache some sockets for each host. */ if (socklist[host] == INVALID_SOCKET) { /* XXX 4.2/4.3BSD has PF_xxx = AF_xxx, so the socket creation here will work properly... */ @@ -136,22 +139,22 @@ krb5_sendto_kdc (context, message, realm, reply, use_master) */ #ifdef DEBUG fprintf (stderr, "getting dgram socket in family %d...", - addrs.addrs[host]->sa_family); + addrs.addrs[host]->ai_family); #endif - socklist[host] = socket(addrs.addrs[host]->sa_family, + socklist[host] = socket(addrs.addrs[host]->ai_family, SOCK_DGRAM, 0); if (socklist[host] == INVALID_SOCKET) { #ifdef DEBUG perror ("socket"); - fprintf (stderr, "af was %d\n", addrs.addrs[host]->sa_family); + fprintf (stderr, "af was %d\n", addrs.addrs[host]->ai_family); #endif continue; /* try other hosts */ } #ifdef DEBUG { char addrbuf[NI_MAXHOST], portbuf[NI_MAXSERV]; - if (0 != getnameinfo (addrs.addrs[host], - socklen (addrs.addrs[host]), + if (0 != getnameinfo (addrs.addrs[host]->ai_addr, + addrs.addrs[host]->ai_addrlen, addrbuf, sizeof (addrbuf), portbuf, sizeof (portbuf), NI_NUMERICHOST | NI_NUMERICSERV)) @@ -167,7 +170,7 @@ krb5_sendto_kdc (context, message, realm, reply, use_master) sendto, recvfrom. The connect here may return an error if the destination host is known to be unreachable. */ if (connect(socklist[host], - addrs.addrs[host], socklen(addrs.addrs[host])) == SOCKET_ERROR) { + addrs.addrs[host]->ai_addr, addrs.addrs[host]->ai_addrlen) == SOCKET_ERROR) { #ifdef DEBUG perror ("connect"); #endif diff --git a/src/lib/krb5/os/t_locate_kdc.c b/src/lib/krb5/os/t_locate_kdc.c index e93b6d8776..5bb334b6df 100644 --- a/src/lib/krb5/os/t_locate_kdc.c +++ b/src/lib/krb5/os/t_locate_kdc.c @@ -27,18 +27,34 @@ void kfatal (krb5_error_code err) exit (1); } +const char *stypename (int stype) +{ + static char buf[20]; + switch (stype) { + case SOCK_STREAM: + return "stream"; + case SOCK_DGRAM: + return "dgram"; + case SOCK_RAW: + return "raw"; + default: + sprintf(buf, "?%d", stype); + return buf; + } +} + void print_addrs () { int i; - struct sockaddr **addrs = al.addrs; + struct addrinfo **addrs = al.addrs; int naddrs = al.naddrs; printf ("%d addresses:\n", naddrs); for (i = 0; i < naddrs; i++) { int err; char hostbuf[NI_MAXHOST], srvbuf[NI_MAXSERV]; - err = getnameinfo (addrs[i], socklen(addrs[i]), + err = getnameinfo (addrs[i]->ai_addr, addrs[i]->ai_addrlen, hostbuf, sizeof (hostbuf), srvbuf, sizeof (srvbuf), NI_NUMERICHOST | NI_NUMERICSERV); @@ -46,7 +62,8 @@ void print_addrs () printf ("%2d: getnameinfo returns error %d=%s\n", i, err, gai_strerror (err)); else - printf ("%2d: address %s\tport %s\n", i, hostbuf, srvbuf); + printf ("%2d: address %s\t%s\tport %s\n", i, hostbuf, + stypename (addrs[i]->ai_socktype), srvbuf); } } |