From 65184d3858714e1a326f18053f6509050b069518 Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Sat, 7 Dec 2002 04:14:07 +0000 Subject: [PATCH] Fix some KRB5_CALLCONV botches that were causing trouble for Windows build Update send_to_kdc() to use various krb5 internals to talk to the krb4 KDC. Add a new internal function to optionally return the local address used to talk to the KDC. Many changes to lib/krb5/os to support this. Fix bug in krb5int_sendto() that prevented correct UDP length from being returned. Update callers of internal locate_* and sendto_* functions. ticket: 1189 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15038 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/ChangeLog | 7 + src/include/k5-int.h | 15 +- src/lib/krb4/ChangeLog | 10 + src/lib/krb4/g_ad_tkt.c | 2 +- src/lib/krb4/g_in_tkt.c | 4 +- src/lib/krb4/send_to_kdc.c | 324 ++++++--------------------------- src/lib/krb5/os/ChangeLog | 24 +++ src/lib/krb5/os/accessor.c | 1 + src/lib/krb5/os/changepw.c | 4 +- src/lib/krb5/os/locate_kdc.c | 43 +++-- src/lib/krb5/os/os-proto.h | 2 +- src/lib/krb5/os/sendto_kdc.c | 7 +- src/lib/krb5/os/t_locate_kdc.c | 2 +- src/lib/krb5/os/t_std_conf.c | 2 +- 14 files changed, 150 insertions(+), 297 deletions(-) diff --git a/src/include/ChangeLog b/src/include/ChangeLog index 0cf22ca70..06c7f1666 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,10 @@ +2002-12-06 Tom Yu + + * k5-int.h: Update prototype of krb5int_locate_server() to take + protocol family argument. Update krb5int_access to current call + signatures of locate_kdc() and locate_server(), as well as to add + add_host_to_list() for use by krb4 library. + 2002-11-26 Tom Yu * port-sockets.h: Add SOCKET_CONNECT, SOCKET_GETSOCKNAME, and diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 90d2c9caa..8b1b683d7 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -529,6 +529,8 @@ struct addrlist { #define ADDRLIST_INIT { 0, 0, 0 } extern void krb5int_free_addrlist (struct addrlist *); extern int krb5int_grow_addrlist (struct addrlist *, int); +extern int krb5int_add_host_to_list (struct addrlist *, const char *, + int, int, int, int); krb5_error_code krb5int_locate_server (krb5_context, @@ -546,7 +548,8 @@ krb5int_locate_server (krb5_context, itself. Use 0 for dflport2 if there's no secondary port (most common, except kdc case). */ - int dflport1, int dflport2); + int dflport1, int dflport2, + int family); #endif /* KRB5_LIBOS_PROTO__ */ @@ -1637,15 +1640,15 @@ void krb5int_set_prompt_types /* To keep happy libraries which are (for now) accessing internal stuff */ /* Make sure to increment by one when changing the struct */ -#define KRB5INT_ACCESS_STRUCT_VERSION 5 +#define KRB5INT_ACCESS_STRUCT_VERSION 6 typedef struct _krb5int_access { krb5_error_code (*krb5_locate_kdc) (krb5_context, const krb5_data *, - struct addrlist *, int, int); + struct addrlist *, int, int, int); krb5_error_code (*krb5_locate_server) (krb5_context, const krb5_data *, struct addrlist *, int, const char *, const char *, - int, int, int); + int, int, int, int); void (*free_addrlist) (struct addrlist *); unsigned int krb5_max_skdc_timeout; unsigned int krb5_skdc_timeout_shift; @@ -1660,6 +1663,10 @@ typedef struct _krb5int_access { krb5_error_code (*sendto_udp) (krb5_context, const krb5_data *msg, const struct addrlist *, krb5_data *reply, struct sockaddr *, socklen_t *); + krb5_error_code (*add_host_to_list)(struct addrlist *lp, + const char *hostname, + int port, int secport, + int socktype, int family); } krb5int_access; #define KRB5INT_ACCESS_VERSION \ diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog index 95c9d3fd8..e105880a0 100644 --- a/src/lib/krb4/ChangeLog +++ b/src/lib/krb4/ChangeLog @@ -1,3 +1,13 @@ +2002-12-06 Tom Yu + + * g_ad_tkt.c (get_ad_tkt): Add KRB5_CALLCONV. + + * g_in_tkt.c (krb_get_in_tkt_preauth): Add KRB5_CALLCONV. + (krb_get_in_tkt): Add KRB5_CALLCONV. + + * send_to_kdc.c (krb4int_send_to_kdc_addr): New function; does + what send_to_kdc() used to do but can also return local address. + 2002-12-05 Tom Yu * kname_parse.c (kname_unparse): Add new function ported from diff --git a/src/lib/krb4/g_ad_tkt.c b/src/lib/krb4/g_ad_tkt.c index 4f77f2a6a..1558b65a1 100644 --- a/src/lib/krb4/g_ad_tkt.c +++ b/src/lib/krb4/g_ad_tkt.c @@ -225,7 +225,7 @@ g_ad_tkt_parse(KTEXT rpkt, C_Block tgtses, C_Block ses, return 0; } -int +int KRB5_CALLCONV get_ad_tkt(service, sinstance, realm, lifetime) char *service; char *sinstance; diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c index 43997a698..7ad053482 100644 --- a/src/lib/krb4/g_in_tkt.c +++ b/src/lib/krb4/g_in_tkt.c @@ -463,7 +463,7 @@ krb_get_in_tkt_creds(user, instance, realm, service, sinstance, life, NULL, 0, creds); } -int +int KRB5_CALLCONV krb_get_in_tkt_preauth(user, instance, realm, service, sinstance, life, key_proc, decrypt_proc, arg, preauth_p, preauth_len) @@ -511,7 +511,7 @@ krb_get_in_tkt_preauth(user, instance, realm, service, sinstance, life, return retval; } -int +int KRB5_CALLCONV krb_get_in_tkt(user, instance, realm, service, sinstance, life, key_proc, decrypt_proc, arg) char *user; diff --git a/src/lib/krb4/send_to_kdc.c b/src/lib/krb4/send_to_kdc.c index 701b975fd..ce602105d 100644 --- a/src/lib/krb4/send_to_kdc.c +++ b/src/lib/krb4/send_to_kdc.c @@ -13,6 +13,7 @@ #include "krbports.h" #include "prot.h" #include +#include #include #ifdef HAVE_SYS_SELECT_H #include @@ -21,22 +22,18 @@ #include #endif #include "port-sockets.h" +#include "fake-addrinfo.h" +#include "k5-int.h" +#include "krb4int.h" #define S_AD_SZ sizeof(struct sockaddr_in) -#ifdef HAVE_STDLIB_H -#include -#else -extern char *malloc(), *calloc(), *realloc(); -#endif - +/* These are really defaults from getservbyname() or hardcoded. */ static int cached_krb_udp_port = 0; static int cached_krbsec_udp_port = 0; -static int -send_recv (KTEXT pkt, KTEXT rpkt, SOCKET f, - struct sockaddr_in *_to, struct hostent *addrs); - +int krb4int_send_to_kdc_addr(KTEXT, KTEXT, char *, + struct sockaddr *, socklen_t *); #ifdef DEBUG static char *prog = "send_to_kdc"; @@ -71,50 +68,44 @@ static char *prog = "send_to_kdc"; */ int -send_to_kdc(pkt,rpkt,realm) - KTEXT pkt; - KTEXT rpkt; - char *realm; +krb4int_send_to_kdc_addr( + KTEXT pkt, KTEXT rpkt, char *realm, + struct sockaddr *addr, socklen_t *addrlen) { - int i; - SOCKET f; - int no_host; /* was a kerberos host found? */ - int retry; - int n_hosts; - int retval; - struct sockaddr_in to; - struct hostent *farkedhost; - struct hostent *host, *hostlist; - char *cp; - char krbhst[MAXHOSTNAMELEN]; - char lrealm[REALM_SZ]; - char *scol; - int krb_udp_port = 0; - int krbsec_udp_port = 0; + struct addrlist al = ADDRLIST_INIT; + char lrealm[REALM_SZ]; + krb5int_access internals; + krb5_error_code retval; + struct servent *sp; + int krb_udp_port = 0; + int krbsec_udp_port = 0; + char krbhst[MAXHOSTNAMELEN]; + char *scol; + int i; + int err; + krb5_data message, reply; /* * If "realm" is non-null, use that, otherwise get the * local realm. */ if (realm) - (void) strncpy(lrealm, realm, sizeof(lrealm) - 1); - else - if (krb_get_lrealm(lrealm,1)) { + strncpy(lrealm, realm, sizeof(lrealm) - 1); + else { + if (krb_get_lrealm(lrealm, 1)) { DEB (("%s: can't get local realm\n", prog)); - return(SKDC_CANT); + return SKDC_CANT; } + } lrealm[sizeof(lrealm) - 1] = '\0'; DEB (("lrealm is %s\n", lrealm)); - if (SOCKET_INITIALIZE()) { - DEB (("%s: can't initialize sockets library\n",prog)); - return (SKDC_CANT); - } - /* from now on, exit through rtn label for cleanup */ + retval = krb5int_accessor(&internals, KRB5INT_ACCESS_VERSION); + if (retval) + return KFAILURE; /* The first time, decide what port to use for the KDC. */ if (cached_krb_udp_port == 0) { - register struct servent *sp; sp = getservbyname("kerberos","udp"); if (sp) cached_krb_udp_port = sp->s_port; @@ -126,7 +117,6 @@ send_to_kdc(pkt,rpkt,realm) as a fallback. */ if (cached_krbsec_udp_port == 0 && cached_krb_udp_port != htons(KERBEROS_PORT)) { - register struct servent *sp; sp = getservbyname("kerberos-sec","udp"); if (sp) cached_krbsec_udp_port = sp->s_port; @@ -135,44 +125,6 @@ send_to_kdc(pkt,rpkt,realm) DEB (("cached_krbsec_udp_port is %d\n", cached_krbsec_udp_port)); } - memset((char *)&to, 0, S_AD_SZ); - hostlist = (struct hostent *) malloc(sizeof(struct hostent)); - if (!hostlist) { - retval = /*errno */SKDC_CANT; - goto rtn_clean; /* Run SOCKET_CLEANUP then return. */ - } - hostlist->h_name = 0; /* so it gets properly freed at "rtn" */ - - f = socket(AF_INET, SOCK_DGRAM, 0); - if (f == INVALID_SOCKET) { - DEB (("%s: Can't open socket\n", prog)); - retval = /*errno */SKDC_CANT; - goto rtn_clean; /* Run SOCKET_CLEANUP then return. */ - } - -/* -** FIXME! FTP Software's WINSOCK implmentation insists that -** a socket be bound before it can receive datagrams. -** This is outside specs. Since it shouldn't hurt any -** other implementations we'll go ahead and do it for -** now. -*/ - { - struct sockaddr_in from; - memset ((char *)&from, 0, S_AD_SZ); - from.sin_family = AF_INET; - from.sin_addr.s_addr = INADDR_ANY; - if ( bind(f, (struct sockaddr *)&from, S_AD_SZ) == SOCKET_ERROR ) { - DEB (("%s : Can't bind\n", prog)); - retval = SKDC_CANT; - goto rtn; - } - } -/* End of kludge (FIXME) for FTP Software WinSock stack. */ - - no_host = 1; - /* get an initial allocation */ - n_hosts = 0; for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) { #ifdef DEBUG if (krb_debug) { @@ -197,200 +149,42 @@ send_to_kdc(pkt,rpkt,realm) krb_udp_port = cached_krb_udp_port; krbsec_udp_port = cached_krbsec_udp_port; } - farkedhost = gethostbyname(krbhst); -#ifdef DEBUG - if (krb_debug) { - DEB (("%s.\n", farkedhost ? "Got it" : "Didn't get it")); - (void) fflush(stdout); - } -#endif - if (!farkedhost) - continue; - no_host = 0; /* found at least one */ - n_hosts++; - /* preserve host network address to check later - * (would be better to preserve *all* addresses, - * take care of that later) - */ - hostlist = (struct hostent *) - realloc((char *)hostlist, - (unsigned) - sizeof(struct hostent)*(n_hosts+1)); - if (!hostlist) { - retval = /*errno */SKDC_CANT; - goto rtn; - } - hostlist[n_hosts-1] = *farkedhost; /* Copy into array */ - memset((char *)&hostlist[n_hosts], 0, sizeof(struct hostent)); - host = &hostlist[n_hosts-1]; - cp = malloc((unsigned)host->h_length); - if (!cp) { - retval = /*errno */SKDC_CANT; - goto rtn; - } - memcpy(cp, host->h_addr, host->h_length); - -/* At least Sun OS version 3.2 (or worse) and Ultrix version 2.2 - (or worse) only return one name ... */ -#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) - host->h_addr_list = (char **)malloc(sizeof(char *)); - if (!host->h_addr_list) { - retval = /*errno */SKDC_CANT; - goto rtn; - } -#endif /* ULTRIX022 || SunOS */ - host->h_addr = cp; - to.sin_family = host->h_addrtype; - memcpy((char *)&to.sin_addr, host->h_addr, - host->h_length); - to.sin_port = krb_udp_port; - if (send_recv(pkt, rpkt, f, &to, hostlist)) { - retval = KSUCCESS; - goto rtn; - } - if (krbsec_udp_port) { - to.sin_port = krbsec_udp_port; - if (send_recv(pkt, rpkt, f, &to, hostlist)) { - retval = KSUCCESS; - goto rtn; - } + err = internals.add_host_to_list(&al, krbhst, + krb_udp_port, krbsec_udp_port, + SOCK_DGRAM, PF_INET); + if (err) { + retval = SKDC_CANT; + goto free_al; } - DEB (("Timeout, error, or wrong descriptor\n")); } - if (no_host) { + if (al.naddrs == 0) { DEB (("%s: can't find any Kerberos host.\n", prog)); retval = SKDC_CANT; - goto rtn; } - /* retry each host in sequence */ - for (retry = 0; retry < CLIENT_KRB_RETRY; ++retry) { - for (host = hostlist; host->h_name != (char *)NULL; host++) { - to.sin_family = host->h_addrtype; - memcpy((char *)&to.sin_addr, host->h_addr, - host->h_length); - if (send_recv(pkt, rpkt, f, &to, hostlist)) { - retval = KSUCCESS; - goto rtn; - } - } - } - retval = SKDC_RETRY; -rtn: - (void) closesocket (f); -rtn_clean: - SOCKET_CLEANUP(); /* Done with using sockets for awhile */ - if (hostlist) { - register struct hostent *hp; - for (hp = hostlist; hp->h_name; hp++) -#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) - if (hp->h_addr_list) { -#endif /* ULTRIX022 || SunOS */ - if (hp->h_addr) - free(hp->h_addr); -#if !(defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)) - free((char *)hp->h_addr_list); - } -#endif /* ULTRIX022 || SunOS */ - free((char *)hostlist); - } - return(retval); + message.length = pkt->length; + message.data = (char *)pkt->dat; /* XXX yuck */ + retval = internals.sendto_udp(NULL, &message, &al, &reply, addr, + addrlen); + DEB(("sendto_udp returns %d\n", retval)); +free_al: + internals.free_addrlist(&al); + if (retval) + return SKDC_CANT; + DEB(("reply.length=%d\n", reply.length)); + if (reply.length > sizeof(rpkt->dat)) + retval = SKDC_CANT; + rpkt->length = 0; + if (!retval) { + memcpy(rpkt->dat, reply.data, reply.length); + rpkt->length = reply.length; + } + krb5_free_data_contents(NULL, &reply); + return retval; } -/* - * try to send out and receive message. - * return 1 on success, 0 on failure - */ - -static int -send_recv(pkt,rpkt,f,_to,addrs) - KTEXT pkt; - KTEXT rpkt; - SOCKET f; - struct sockaddr_in *_to; - struct hostent *addrs; +int +send_to_kdc(KTEXT pkt, KTEXT rpkt, char *realm) { - fd_set readfds; - register struct hostent *hp; - struct sockaddr_in from; - int sin_size; - int numsent; - int selresult; - int recvresult; - struct timeval timeout; - -#ifdef DEBUG - if (krb_debug) { - if (_to->sin_family == AF_INET) { - printf("Sending message to "); - far_fputs (inet_ntoa(_to->sin_addr), stdout); - printf("..."); - } else - printf("Sending message..."); - (void) fflush(stdout); - } -#endif - if ((numsent = sendto(f,(char *)(pkt->dat), pkt->length, 0, - (struct sockaddr *)_to, - S_AD_SZ)) != pkt->length) { - DEB (("sent only %d/%d\n",numsent, pkt->length)); - return 0; - } -#ifdef DEBUG - if (krb_debug) { - printf("Sent\nWaiting for reply..."); - (void) fflush(stdout); - } -#endif - FD_ZERO(&readfds); - FD_SET(f, &readfds); - SOCKET_SET_ERRNO (0); - - /* select - either recv is ready, or timeout */ - /* see if timeout or error or wrong descriptor */ - /* Need to fill in the timeout structure each time, because on some - systems -- e.g., Linux -- the timeout will be modified in place - by the select syscall. */ - timeout.tv_sec = CLIENT_KRB_TIMEOUT; - timeout.tv_usec = 0; - selresult = select(SOCKET_NFDS(f), &readfds, (fd_set *)0, (fd_set *)0, - &timeout); - if (selresult != 1 || !FD_ISSET(f, &readfds)) { -#ifdef DEBUG - if (krb_debug) { - fprintf(stderr, "select failed: selresult=%d, readfds=%x, errno=%d", - selresult, readfds, SOCKET_ERRNO); - perror(""); - } -#endif - return 0; - } - - sin_size = sizeof(from); - recvresult = recvfrom(f, (char *)(rpkt->dat), sizeof(rpkt->dat), 0, - (struct sockaddr *)&from, &sin_size); - if (recvresult < 0) { - DEB (("Recvfrom error %d\n", SOCKET_ERRNO)); - return 0; - } - rpkt->length = recvresult; -#ifdef DEBUG - if (krb_debug) { - printf("received packet from "); - far_fputs (inet_ntoa(from.sin_addr), stdout); - printf("\n"); - fflush(stdout); - } -#endif - for (hp = addrs; hp->h_name != (char *)NULL; hp++) { - if (!memcmp(hp->h_addr, (char *)&from.sin_addr.s_addr, - hp->h_length)) { - DEB (("Received it\n")); - return 1; - } - DEB (("packet not from %x\n", hp->h_addr)); - } - DEB (("%s: received packet from wrong host! (%x)\n", - "send_to_kdc(send_rcv)", from.sin_addr.s_addr)); - return 0; + return krb4int_send_to_kdc_addr(pkt, rpkt, realm, NULL, NULL); } diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index 6c57cfbca..059fb8913 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,27 @@ +2002-12-06 Tom Yu + + * accessor.c (krb5int_accessor): Add add_host_to_list. + + * changepw.c (krb5_locate_kpasswd): Update calls to + krb5_locate_kdc(). + + * locate_kdc.c (add_host_to_list): Renamed to + krb5int_add_host_to_list(), with macro to deal with existing + callers in this file. Now takes an argument to indicate protocol + family. Callers updated accordingly to also take protocol family + arguments. + + * os-proto.h: Update prototype of krb5_locate_kdc(). + + * sendto_kdc.c (krb5_sendto_kdc): Update calls to + krb5_locate_kdc(). + (krb5int_sendto): UDP reply length is in.pos-in.buf, not + in.bufsize. + + * t_locate_kdc.c (main): Update call to krb5_locate_kdc(). + + * t_std_conf.c (test_locate_kdc): Update call to krb5_locate_kdc(). + 2002-11-14 Tom Yu * changepw.c: Remove reference to adm_err.h. diff --git a/src/lib/krb5/os/accessor.c b/src/lib/krb5/os/accessor.c index 400892405..509d317fa 100644 --- a/src/lib/krb5/os/accessor.c +++ b/src/lib/krb5/os/accessor.c @@ -46,6 +46,7 @@ krb5int_accessor(krb5int_access *internals, krb5_int32 version) internals_temp.md5_hash_provider = &krb5int_hash_md5; internals_temp.arcfour_enc_provider = &krb5int_enc_arcfour; internals_temp.sendto_udp = &krb5int_sendto; + internals_temp.add_host_to_list = krb5int_add_host_to_list; *internals = internals_temp; return 0; } diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c index 17de039ba..60cb3a915 100644 --- a/src/lib/krb5/os/changepw.c +++ b/src/lib/krb5/os/changepw.c @@ -49,11 +49,11 @@ krb5_locate_kpasswd(krb5_context context, const krb5_data *realm, code = krb5int_locate_server (context, realm, addrlist, 0, "kpasswd_server", "_kpasswd", 0, - DEFAULT_KPASSWD_PORT, 0); + DEFAULT_KPASSWD_PORT, 0, 0); if (code) { code = krb5int_locate_server (context, realm, addrlist, 0, "admin_server", "_kerberos-adm", 1, - DEFAULT_KPASSWD_PORT, 0); + DEFAULT_KPASSWD_PORT, 0, 0); if (!code) { /* Success with admin_server but now we need to change the port number to use DEFAULT_KPASSWD_PORT. */ diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c index 451d3e982..8dbd55303 100644 --- a/src/lib/krb5/os/locate_kdc.c +++ b/src/lib/krb5/os/locate_kdc.c @@ -243,9 +243,12 @@ static int add_addrinfo_to_list (struct addrlist *lp, struct addrinfo *a) return 0; } -static int -add_host_to_list (struct addrlist *lp, const char *hostname, - int port, int secport, int socktype) +#define add_host_to_list krb5int_add_host_to_list + +int +krb5int_add_host_to_list (struct addrlist *lp, const char *hostname, + int port, int secport, + int socktype, int family) { struct addrinfo *addrs, *a, *anext, hint; int err; @@ -257,6 +260,7 @@ add_host_to_list (struct addrlist *lp, const char *hostname, #endif memset(&hint, 0, sizeof(hint)); + hint.ai_family = family; hint.ai_socktype = socktype; sprintf(portbuf, "%d", ntohs(port)); sprintf(secportbuf, "%d", ntohs(secport)); @@ -303,7 +307,7 @@ static krb5_error_code krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm, const char * name, struct addrlist *addrlist, int get_masters, int socktype, - int udpport, int sec_udpport) + int udpport, int sec_udpport, int family) { const char *realm_srv_names[4]; char **masterlist, **hostlist, *host, *port, *cp; @@ -454,13 +458,14 @@ krb5_locate_srv_conf_1(krb5_context context, const krb5_data *realm, } if (socktype != 0) - code = add_host_to_list (addrlist, hostlist[i], p1, p2, socktype); + code = add_host_to_list (addrlist, hostlist[i], p1, p2, + socktype, family); else { code = add_host_to_list (addrlist, hostlist[i], p1, p2, - SOCK_DGRAM); + SOCK_DGRAM, family); if (code == 0) code = add_host_to_list (addrlist, hostlist[i], p1, p2, - SOCK_STREAM); + SOCK_STREAM, family); } if (code) { #ifdef TEST @@ -491,7 +496,7 @@ krb5_locate_srv_conf(krb5_context context, const krb5_data *realm, krb5_error_code ret; ret = krb5_locate_srv_conf_1 (context, realm, name, al, - get_masters, 0, udpport, sec_udpport); + get_masters, 0, udpport, sec_udpport, 0); if (ret) return ret; if (al->naddrs == 0) /* Couldn't resolve any KDC names */ @@ -510,7 +515,8 @@ static krb5_error_code krb5_locate_srv_dns_1 (const krb5_data *realm, const char *service, const char *protocol, - struct addrlist *addrlist) + struct addrlist *addrlist, + int family) { union { unsigned char bytes[2048]; @@ -721,7 +727,7 @@ krb5_locate_srv_dns_1 (const krb5_data *realm, code = add_host_to_list (addrlist, entry->host, htons (entry->port), 0, (strcmp("_tcp", protocol) ? SOCK_DGRAM - : SOCK_STREAM)); + : SOCK_STREAM), family); if (code) break; } @@ -751,7 +757,7 @@ krb5_locate_srv_dns(const krb5_data *realm, const char *service, const char *protocol, struct addrlist *al) { - return krb5_locate_srv_dns_1 (realm, service, protocol, al); + return krb5_locate_srv_dns_1 (realm, service, protocol, al, 0); } #endif #endif /* KRB5_DNS_LOOKUP */ @@ -767,7 +773,8 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm, const char *profname, const char *dnsname, int socktype, /* network order port numbers! */ - int dflport1, int dflport2) + int dflport1, int dflport2, + int family) { krb5_error_code code; struct addrlist al = ADDRLIST_INIT; @@ -779,7 +786,7 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm, */ code = krb5_locate_srv_conf_1(context, realm, profname, &al, get_masters, - socktype, dflport1, dflport2); + socktype, dflport1, dflport2, family); #ifdef KRB5_DNS_LOOKUP if (code && dnsname != 0) { @@ -787,7 +794,8 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm, if (use_dns) { code = 0; if (socktype == SOCK_DGRAM || socktype == 0) { - code = krb5_locate_srv_dns_1(realm, dnsname, "_udp", &al); + code = krb5_locate_srv_dns_1(realm, dnsname, "_udp", + &al, family); #ifdef TEST if (code) fprintf(stderr, "dns udp lookup returned error %d\n", @@ -795,7 +803,8 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm, #endif } if ((socktype == SOCK_STREAM || socktype == 0) && code == 0) { - code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp", &al); + code = krb5_locate_srv_dns_1(realm, dnsname, "_tcp", + &al, family); #ifdef TEST if (code) fprintf(stderr, "dns tcp lookup returned error %d\n", @@ -830,7 +839,7 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm, krb5_error_code krb5_locate_kdc(krb5_context context, const krb5_data *realm, struct addrlist *addrlist, - int get_masters, int socktype) + int get_masters, int socktype, int family) { int udpport, sec_udpport; @@ -850,5 +859,5 @@ krb5_locate_kdc(krb5_context context, const krb5_data *realm, (get_masters ? "_kerberos-master" : "_kerberos"), - socktype, udpport, sec_udpport); + socktype, udpport, sec_udpport, family); } diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h index f474fa04e..bc26a1dd9 100644 --- a/src/lib/krb5/os/os-proto.h +++ b/src/lib/krb5/os/os-proto.h @@ -32,7 +32,7 @@ struct addrlist; krb5_error_code krb5_locate_kdc - (krb5_context, const krb5_data *, struct addrlist *, int, int); + (krb5_context, const krb5_data *, struct addrlist *, int, int, int); #ifdef HAVE_NETINET_IN_H krb5_error_code krb5_unpack_full_ipaddr diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c index 687f4e079..300e9777e 100644 --- a/src/lib/krb5/os/sendto_kdc.c +++ b/src/lib/krb5/os/sendto_kdc.c @@ -308,12 +308,12 @@ krb5_sendto_kdc (krb5_context context, const krb5_data *message, else socktype1 = SOCK_STREAM, socktype2 = SOCK_DGRAM; - retval = krb5_locate_kdc(context, realm, &addrs, use_master, socktype1); + retval = krb5_locate_kdc(context, realm, &addrs, use_master, socktype1, 0); if (socktype2) { struct addrlist addrs2; retval = krb5_locate_kdc(context, realm, &addrs2, use_master, - socktype2); + socktype2, 0); if (retval == 0) { (void) merge_addrlists(&addrs, &addrs2); krb5int_free_addrlist(&addrs2); @@ -1061,7 +1061,8 @@ krb5int_sendto (krb5_context context, const krb5_data *message, } /* Success! */ reply->data = conns[winning_conn].x.in.buf; - reply->length = conns[winning_conn].x.in.bufsize; + reply->length = (conns[winning_conn].x.in.pos + - conns[winning_conn].x.in.buf); dprint("returning %d bytes in buffer %p\n", (int) reply->length, reply->data); retval = 0; diff --git a/src/lib/krb5/os/t_locate_kdc.c b/src/lib/krb5/os/t_locate_kdc.c index 8365c03a7..a3d682860 100644 --- a/src/lib/krb5/os/t_locate_kdc.c +++ b/src/lib/krb5/os/t_locate_kdc.c @@ -121,7 +121,7 @@ int main (int argc, char *argv[]) break; case LOOKUP_WHATEVER: - err = krb5_locate_kdc (ctx, &realm, &al, master, 0); + err = krb5_locate_kdc (ctx, &realm, &al, master, 0, 0); break; } if (err) kfatal (err); diff --git a/src/lib/krb5/os/t_std_conf.c b/src/lib/krb5/os/t_std_conf.c index 407d44cab..adaf6893d 100644 --- a/src/lib/krb5/os/t_std_conf.c +++ b/src/lib/krb5/os/t_std_conf.c @@ -106,7 +106,7 @@ static void test_locate_kdc(krb5_context ctx, char *realm) rlm.data = realm; rlm.length = strlen(realm); - retval = krb5_locate_kdc(ctx, &rlm, &addrs, get_masters, 0); + retval = krb5_locate_kdc(ctx, &rlm, &addrs, get_masters, 0, 0); if (retval) { com_err("krb5_locate_kdc", retval, 0); return; -- 2.26.2