summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--src/include/ChangeLog5
-rw-r--r--src/include/k5-int.h4
-rw-r--r--src/krb524/ChangeLog5
-rw-r--r--src/krb524/sendmsg.c11
-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
9 files changed, 152 insertions, 106 deletions
diff --git a/src/include/ChangeLog b/src/include/ChangeLog
index 2fdec29145..0872f7104d 100644
--- a/src/include/ChangeLog
+++ b/src/include/ChangeLog
@@ -1,3 +1,8 @@
+2002-06-04 Ken Raeburn <raeburn@mit.edu>
+
+ * k5-int.h (struct addrlist): Field "addrs" now points to
+ addrinfo instead of sockaddr.
+
2002-05-31 Ken Raeburn <raeburn@mit.edu>
* socket-utils.h (socklen) [! HAVE_SA_LEN]: Return a socklen_t
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 1b90386f5b..e53585a15c 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -485,8 +485,10 @@ krb5_error_code krb5_find_config_files (void);
krb5_error_code krb5_os_hostaddr
(krb5_context, const char *, krb5_address ***);
+/* N.B.: You need to include fake-addrinfo.h *before* k5-int.h if you're
+ going to use this structure. */
struct addrlist {
- struct sockaddr **addrs;
+ struct addrinfo **addrs;
int naddrs;
int space;
};
diff --git a/src/krb524/ChangeLog b/src/krb524/ChangeLog
index 68b0a832a1..6f35970ede 100644
--- a/src/krb524/ChangeLog
+++ b/src/krb524/ChangeLog
@@ -1,3 +1,8 @@
+2002-06-04 Ken Raeburn <raeburn@mit.edu>
+
+ * sendmsg.c: Include fake-addrinfo.h.
+ (krb524_sendto_kdc): Update for addrlist changes.
+
2002-04-10 Danilo Almeida <dalmeida@mit.edu>
* encode.c, cnv_tkt_skey.c: Need port-sockets.h for Win32 (now
diff --git a/src/krb524/sendmsg.c b/src/krb524/sendmsg.c
index 00c55f0d2a..2335dad316 100644
--- a/src/krb524/sendmsg.c
+++ b/src/krb524/sendmsg.c
@@ -28,6 +28,7 @@
/* Grab socket stuff. This might want to go away later. */
#define NEED_SOCKETS
#define NEED_LOWLEVEL_IO
+#include "fake-addrinfo.h" /* for custom addrinfo if needed */
#include "k5-int.h"
#ifndef _WIN32
@@ -101,8 +102,8 @@ krb524_sendto_kdc (context, message, realm, reply)
*/
if (retval == 0)
for (i = 0; i < al.naddrs; i++) {
- if (al.addrs[i]->sa_family == AF_INET)
- sa2sin (al.addrs[i])->sin_port = port;
+ if (al.addrs[i]->ai_family == AF_INET)
+ sa2sin (al.addrs[i]->ai_addr)->sin_port = port;
}
}
if (retval)
@@ -163,7 +164,7 @@ krb524_sendto_kdc (context, message, realm, reply)
* protocol exists to support a particular socket type
* within a given protocol family.
*/
- socklist[host] = socket(al.addrs[host]->sa_family, SOCK_DGRAM,
+ socklist[host] = socket(al.addrs[host]->ai_family, SOCK_DGRAM,
0);
if (socklist[host] == INVALID_SOCKET)
continue; /* try other hosts */
@@ -173,8 +174,8 @@ krb524_sendto_kdc (context, message, realm, reply)
socket will time out, so use connect, send, recv instead of
sendto, recvfrom. The connect here may return an error if
the destination host is known to be unreachable. */
- if (connect(socklist[host], al.addrs[host],
- socklen(al.addrs[host])) == SOCKET_ERROR)
+ if (connect(socklist[host], al.addrs[host]->ai_addr,
+ al.addrs[host]->ai_addrlen) == SOCKET_ERROR)
continue;
}
if (send(socklist[host], message->data, (int) message->length, 0)
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);
}
}