From 3ef1ecb6226c6d976b2eccc4d6882c7dafa466fa Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Wed, 20 Jun 2001 00:00:05 +0000 Subject: Use a "struct addrlist" instead of separate count and pointer-to-pointer values for internal interfaces for looking up servers. Add a new routine to free the addrlist contents, so that memory management can be changed in one place. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13390 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/os/ChangeLog | 23 +++++++++++++++++ src/lib/krb5/os/accessor.c | 1 + src/lib/krb5/os/changepw.c | 50 ++++++++++++++++++------------------- src/lib/krb5/os/locate_kdc.c | 59 +++++++++++++++----------------------------- src/lib/krb5/os/os-proto.h | 6 +---- src/lib/krb5/os/sendto_kdc.c | 34 ++++++++++++------------- 6 files changed, 87 insertions(+), 86 deletions(-) (limited to 'src/lib') 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 + + * 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 * 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;inaddrs;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; isa_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); -- cgit