summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/krb5/os/ChangeLog23
-rw-r--r--src/lib/krb5/os/accessor.c1
-rw-r--r--src/lib/krb5/os/changepw.c50
-rw-r--r--src/lib/krb5/os/locate_kdc.c59
-rw-r--r--src/lib/krb5/os/os-proto.h6
-rw-r--r--src/lib/krb5/os/sendto_kdc.c34
6 files changed, 87 insertions, 86 deletions
diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog
index 2767311a5..137ef7680 100644
--- a/src/lib/krb5/os/ChangeLog
+++ b/src/lib/krb5/os/ChangeLog
@@ -1,3 +1,26 @@
+2001-06-19 Ken Raeburn <raeburn@mit.edu>
+
+ * locate_kdc.c (struct addrlist, ADDRLIST_INIT): Moved to
+ k5-int.h.
+ (krb5int_free_addrlist): Renamed from free_list; no longer
+ static.
+ (krb5_locate_srv_conf, krb5_locate_srv_dns, krb5int_locate_server,
+ krb5_locate_kdc): Use addrlist in interface.
+
+ * sendto_kdc.c (krb5_sendto_kdc): Use new struct addrlist
+ interface.
+
+ * changepw.c (krb5_locate_kpasswd): Use addrlist structure in
+ interface and implementation.
+ (krb5_change_password): Likewise.
+
+ * accessor.c (krb5int_accessor): Fill in free_addrlist function
+ pointer field.
+
+ * os-proto.h (krb5_locate_kdc): Update prototype.
+
+ * t_std_conf.c (test_locate_kdc): Update tests for new API.
+
2001-06-12 Ezra Peisach <epeisach@mit.edu>
* sn2princ.c, hst_realm.c, an_to_ln.c: Cast argument to
diff --git a/src/lib/krb5/os/accessor.c b/src/lib/krb5/os/accessor.c
index d3c842a86..bcf89a7b6 100644
--- a/src/lib/krb5/os/accessor.c
+++ b/src/lib/krb5/os/accessor.c
@@ -39,6 +39,7 @@ krb5int_accessor(internals, version)
krb5int_access internals_temp;
internals_temp.krb5_locate_server = krb5int_locate_server;
internals_temp.krb5_locate_kdc = krb5_locate_kdc;
+ internals_temp.free_addrlist = krb5int_free_addrlist;
internals_temp.krb5_max_skdc_timeout = krb5_max_skdc_timeout;
internals_temp.krb5_skdc_timeout_shift = krb5_skdc_timeout_shift;
internals_temp.krb5_skdc_timeout_1 = krb5_skdc_timeout_1;
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
index 0a6d0e5ee..7153b75ec 100644
--- a/src/lib/krb5/os/changepw.c
+++ b/src/lib/krb5/os/changepw.c
@@ -54,27 +54,24 @@
*/
static krb5_error_code
-krb5_locate_kpasswd(context, realm, addr_pp, naddrs)
- krb5_context context;
- const krb5_data *realm;
- struct sockaddr ***addr_pp;
- int *naddrs;
+krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
+ struct addrlist *addrlist)
{
krb5_error_code code;
- code = krb5int_locate_server (context, realm, addr_pp, naddrs, 0,
+ code = krb5int_locate_server (context, realm, addrlist, 0,
"kpasswd_server", "_kpasswd", 0,
DEFAULT_KPASSWD_PORT, 0);
if (code) {
- code = krb5int_locate_server (context, realm, addr_pp, naddrs, 0,
+ code = krb5int_locate_server (context, realm, addrlist, 0,
"admin_server", "_kerberos-adm", 1,
DEFAULT_KPASSWD_PORT, 0);
if (!code) {
/* Success with admin_server but now we need to change the
port number to use DEFAULT_KPASSWD_PORT. */
int i;
- for ( i=0;i<*naddrs;i++ ) {
- struct sockaddr *a = (*addr_pp)[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);
}
@@ -100,17 +97,15 @@ krb5_change_password(context, creds, newpw, result_code,
char *code_string;
krb5_error_code code = 0;
int i, addrlen;
- struct sockaddr **addr_p;
struct sockaddr_storage local_addr, remote_addr, tmp_addr;
- int naddr_p;
int cc, local_result_code, tmp_len;
SOCKET s1 = INVALID_SOCKET, s2 = INVALID_SOCKET;
int tried_one = 0;
+ struct addrlist al = ADDRLIST_INIT;
/* Initialize values so that cleanup call can safely check for NULL */
auth_context = NULL;
- addr_p = NULL;
memset(&chpw_req, 0, sizeof(krb5_data));
memset(&chpw_rep, 0, sizeof(krb5_data));
memset(&ap_req, 0, sizeof(krb5_data));
@@ -126,7 +121,7 @@ krb5_change_password(context, creds, newpw, result_code,
if ((code = krb5_locate_kpasswd(context,
krb5_princ_realm(context, creds->client),
- &addr_p, &naddr_p)))
+ &al)))
goto cleanup;
/* this is really obscure. s1 is used for all communications. it
@@ -155,16 +150,23 @@ krb5_change_password(context, creds, newpw, result_code,
goto cleanup;
}
- for (i=0; i<naddr_p; i++) {
+ /*
+ * This really should try fallback addresses in cases of timeouts.
+ * For now, where the MIT KDC implementation only supports one
+ * kpasswd server machine anyways, we'll only try the first IPv4
+ * address we can connect() to. This isn't right for multi-homed
+ * servers; oh well.
+ */
+ for (i=0; i<al.naddrs; i++) {
fd_set fdset;
struct timeval timeout;
/* XXX Now the locate_ functions can return IPv6 addresses. */
- if (addr_p[i]->sa_family != AF_INET)
+ if (al.addrs[i]->sa_family != AF_INET)
continue;
tried_one = 1;
- if (connect(s2, addr_p[i], socklen(addr_p[i])) == SOCKET_ERROR) {
+ if (connect(s2, al.addrs[i], socklen(al.addrs[i])) == SOCKET_ERROR) {
if (SOCKET_ERRNO == ECONNREFUSED || SOCKET_ERRNO == EHOSTUNREACH)
continue; /* try the next addr */
@@ -244,7 +246,7 @@ krb5_change_password(context, creds, newpw, result_code,
}
if ((cc = sendto(s1, chpw_req.data, (int) chpw_req.length, 0,
- addr_p[i], socklen(addr_p[i]))) != chpw_req.length)
+ al.addrs[i], socklen(al.addrs[i]))) != chpw_req.length)
{
if ((cc < 0) && ((SOCKET_ERRNO == ECONNREFUSED) ||
(SOCKET_ERRNO == EHOSTUNREACH)))
@@ -316,9 +318,11 @@ krb5_change_password(context, creds, newpw, result_code,
goto cleanup;
result_code_string->length = strlen(code_string);
- if ((result_code_string->data =
- (char *) malloc(result_code_string->length)) == NULL)
- return(ENOMEM);
+ result_code_string->data = malloc(result_code_string->length);
+ if (result_code_string->data == NULL) {
+ code = ENOMEM;
+ goto cleanup;
+ }
strncpy(result_code_string->data, code_string, result_code_string->length);
}
@@ -339,11 +343,7 @@ cleanup:
if (auth_context != NULL)
krb5_auth_con_free(context, auth_context);
- if (addr_p != NULL) {
- for (i = 0; i < naddr_p; i++)
- krb5_xfree (addr_p[i]);
- krb5_xfree(addr_p);
- }
+ krb5int_free_addrlist (&al);
if (s1 != INVALID_SOCKET)
closesocket(s1);
diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
index c518c1f1f..a4587e089 100644
--- a/src/lib/krb5/os/locate_kdc.c
+++ b/src/lib/krb5/os/locate_kdc.c
@@ -133,13 +133,6 @@ static int get_port (const char *service, int stream, int defalt)
#endif
}
-struct addrlist {
- struct sockaddr **addrs;
- int naddrs;
- int space;
-};
-#define ADDRLIST_INIT { 0, 0, 0 }
-
static int
grow_list (struct addrlist *lp, int nmore)
{
@@ -164,8 +157,10 @@ grow_list (struct addrlist *lp, int nmore)
return 0;
}
-static void
-free_list (struct addrlist *lp)
+/* Free up everything pointed to by the addrlist structure, but don't
+ free the structure itself. */
+void
+krb5int_free_addrlist (struct addrlist *lp)
{
int i;
for (i = 0; i < lp->naddrs; i++)
@@ -174,6 +169,7 @@ free_list (struct addrlist *lp)
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,
@@ -516,29 +512,23 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm,
#ifdef TEST
static krb5_error_code
-krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, get_masters,
+krb5_locate_srv_conf(context, realm, name, al, get_masters,
udpport, sec_udpport)
krb5_context context;
const krb5_data *realm;
const char * name;
- struct sockaddr ***addr_pp;
- int *naddrs;
+ struct addrlist *al;
int get_masters;
int udpport, sec_udpport;
{
krb5_error_code ret;
- struct addrlist al = ADDRLIST_INIT;
- ret = krb5_locate_srv_conf_1 (context, realm, name, &al,
+ ret = krb5_locate_srv_conf_1 (context, realm, name, al,
get_masters, udpport, sec_udpport);
- if (ret) {
- free_list (&al);
+ if (ret)
return ret;
- }
- if (al.naddrs == 0) /* Couldn't resolve any KDC names */
+ if (al->naddrs == 0) /* Couldn't resolve any KDC names */
return KRB5_REALM_CANT_RESOLVE;
- *addr_pp = al.addrs;
- *naddrs = al.naddrs;
return 0;
}
#endif
@@ -789,15 +779,9 @@ krb5_locate_srv_dns_1 (const krb5_data *realm,
static krb5_error_code
krb5_locate_srv_dns(const krb5_data *realm,
const char *service, const char *protocol,
- struct sockaddr ***addr_pp, int *naddrs)
+ struct addrlist *al)
{
- struct addrlist al = ADDRLIST_INIT;
- krb5_error_code code;
-
- code = krb5_locate_srv_dns_1 (realm, service, protocol, &al);
- *addr_pp = al.addrs;
- *naddrs = al.naddrs;
- return code;
+ return krb5_locate_srv_dns_1 (realm, service, protocol, al);
}
#endif
#endif /* KRB5_DNS_LOOKUP */
@@ -808,7 +792,7 @@ krb5_locate_srv_dns(const krb5_data *realm,
krb5_error_code
krb5int_locate_server (krb5_context context, const krb5_data *realm,
- struct sockaddr ***addr_pp, int *naddrs,
+ struct addrlist *addrlist,
int get_masters,
const char *profname, const char *dnsname,
int is_stream,
@@ -818,6 +802,8 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm,
krb5_error_code code;
struct addrlist al = ADDRLIST_INIT;
+ *addrlist = al;
+
/*
* We always try the local file first
*/
@@ -851,18 +837,14 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm,
free_list (&al);
return KRB5_REALM_CANT_RESOLVE;
}
- *addr_pp = al.addrs;
- *naddrs = al.naddrs;
+ *addrlist = al;
return 0;
}
krb5_error_code
-krb5_locate_kdc(context, realm, addr_pp, naddrs, get_masters)
- krb5_context context;
- const krb5_data *realm;
- struct sockaddr ***addr_pp;
- int *naddrs;
- int get_masters;
+krb5_locate_kdc(krb5_context context, const krb5_data *realm,
+ struct addrlist *addrlist,
+ int get_masters)
{
int udpport, sec_udpport;
@@ -874,8 +856,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, get_masters)
if (sec_udpport == udpport)
sec_udpport = 0;
- return krb5int_locate_server (context, realm, addr_pp, naddrs, get_masters,
- "kdc",
+ return krb5int_locate_server (context, realm, addrlist, get_masters, "kdc",
(get_masters
? "_kerberos-master"
: "_kerberos"),
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
index ceba9b477..7be2c3fc6 100644
--- a/src/lib/krb5/os/os-proto.h
+++ b/src/lib/krb5/os/os-proto.h
@@ -32,11 +32,7 @@
#ifdef SOCK_DGRAM /* XXX hack... */
krb5_error_code krb5_locate_kdc
- PROTOTYPE((krb5_context,
- const krb5_data *,
- struct sockaddr ***,
- int *,
- int));
+ PROTOTYPE((krb5_context, const krb5_data *, struct addrlist *, int));
#endif
#ifdef HAVE_NETINET_IN_H
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
index 486066b56..45e6d00b3 100644
--- a/src/lib/krb5/os/sendto_kdc.c
+++ b/src/lib/krb5/os/sendto_kdc.c
@@ -62,37 +62,36 @@ krb5_sendto_kdc (context, message, realm, reply, use_master)
krb5_data * reply;
int use_master;
{
- register int timeout, host, i;
- struct sockaddr **addr;
- int naddr;
+ int timeout, host, i;
int sent, nready;
krb5_error_code retval;
SOCKET *socklist;
fd_set readable;
struct timeval waitlen;
int cc;
+ struct addrlist addrs;
/*
* find KDC location(s) for realm
*/
- if ((retval = krb5_locate_kdc(context, realm, &addr, &naddr, use_master)))
+ if ((retval = krb5_locate_kdc(context, realm, &addrs, use_master)))
return retval;
- if (naddr == 0)
+ if (addrs.naddrs == 0)
return (use_master ? KRB5_KDC_UNREACH : KRB5_REALM_UNKNOWN);
- socklist = (SOCKET *)malloc(naddr * sizeof(SOCKET));
+ socklist = (SOCKET *)malloc(addrs.naddrs * sizeof(SOCKET));
if (socklist == NULL) {
- krb5_xfree(addr);
+ krb5int_free_addrlist (&addrs);
return ENOMEM;
}
- for (i = 0; i < naddr; i++)
+ for (i = 0; i < addrs.naddrs; i++)
socklist[i] = INVALID_SOCKET;
if (!(reply->data = malloc(krb5_max_dgram_size))) {
- for (i = 0; i < naddr; i++)
- krb5_xfree (addr[i]);
- krb5_xfree(addr);
+ for (i = 0; i < addrs.naddrs; i++)
+ krb5_xfree (addrs.addrs[i]);
+ krb5int_free_addrlist (&addrs);
krb5_xfree(socklist);
return ENOMEM;
}
@@ -106,7 +105,7 @@ krb5_sendto_kdc (context, message, realm, reply, use_master)
* See below for commented out SOCKET_CLEANUP()
*/
if (SOCKET_INITIALIZE()) { /* PC needs this for some tcp/ip stacks */
- krb5_xfree(addr);
+ krb5int_free_addrlist (&addrs);
krb5_xfree(socklist);
free(reply->data);
return SOCKET_ERRNO;
@@ -120,7 +119,7 @@ krb5_sendto_kdc (context, message, realm, reply, use_master)
for (timeout = krb5_skdc_timeout_1; timeout < krb5_max_skdc_timeout;
timeout <<= krb5_skdc_timeout_shift) {
sent = 0;
- for (host = 0; host < naddr; host++) {
+ for (host = 0; host < addrs.naddrs; host++) {
/* send to the host, wait timeout seconds for a response,
then move on. */
/* cache some sockets for each host */
@@ -135,7 +134,8 @@ krb5_sendto_kdc (context, message, realm, reply, use_master)
* protocol exists to support a particular socket type
* within a given protocol family.
*/
- socklist[host] = socket(addr[host]->sa_family, SOCK_DGRAM, 0);
+ socklist[host] = socket(addrs.addrs[host]->sa_family,
+ SOCK_DGRAM, 0);
if (socklist[host] == INVALID_SOCKET)
continue; /* try other hosts */
/* have a socket to send/recv from */
@@ -145,7 +145,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],
- addr[host], socklen(addr[host])) == SOCKET_ERROR)
+ addrs.addrs[host], socklen(addrs.addrs[host])) == SOCKET_ERROR)
continue;
}
if (send(socklist[host],
@@ -214,13 +214,13 @@ krb5_sendto_kdc (context, message, realm, reply, use_master)
}
retval = KRB5_KDC_UNREACH;
out:
- for (i = 0; i < naddr; i++)
+ for (i = 0; i < addrs.naddrs; i++)
if (socklist[i] != INVALID_SOCKET)
(void) closesocket (socklist[i]);
#if 0
SOCKET_CLEANUP(); /* Done with sockets for now */
#endif
- krb5_xfree(addr);
+ krb5int_free_addrlist (&addrs);
krb5_xfree(socklist);
if (retval) {
free(reply->data);