summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2002-06-04 06:59:28 +0000
committerKen Raeburn <raeburn@mit.edu>2002-06-04 06:59:28 +0000
commitb02232ffdf69f75caaf10c78e00a9fa8f93b3286 (patch)
tree8324d8d24db2a4b72d95cfe57c7762355e5edd81 /src/lib
parent53c8f6650caef85bb9b38f23e0e50965d50d26f6 (diff)
downloadkrb5-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/ChangeLog26
-rw-r--r--src/lib/krb5/os/changepw.c13
-rw-r--r--src/lib/krb5/os/locate_kdc.c152
-rw-r--r--src/lib/krb5/os/sendto_kdc.c19
-rw-r--r--src/lib/krb5/os/t_locate_kdc.c23
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);
}
}