Fix some KRB5_CALLCONV botches that were causing trouble for Windows build
authorTom Yu <tlyu@mit.edu>
Sat, 7 Dec 2002 04:14:07 +0000 (04:14 +0000)
committerTom Yu <tlyu@mit.edu>
Sat, 7 Dec 2002 04:14:07 +0000 (04:14 +0000)
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

14 files changed:
src/include/ChangeLog
src/include/k5-int.h
src/lib/krb4/ChangeLog
src/lib/krb4/g_ad_tkt.c
src/lib/krb4/g_in_tkt.c
src/lib/krb4/send_to_kdc.c
src/lib/krb5/os/ChangeLog
src/lib/krb5/os/accessor.c
src/lib/krb5/os/changepw.c
src/lib/krb5/os/locate_kdc.c
src/lib/krb5/os/os-proto.h
src/lib/krb5/os/sendto_kdc.c
src/lib/krb5/os/t_locate_kdc.c
src/lib/krb5/os/t_std_conf.c

index 0cf22ca70176d18e504e04a41b0718034aec2d71..06c7f16664a00570181732c33e038b7ec555b436 100644 (file)
@@ -1,3 +1,10 @@
+2002-12-06  Tom Yu  <tlyu@mit.edu>
+
+       * 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  <tlyu@mit.edu>
 
        * port-sockets.h: Add SOCKET_CONNECT, SOCKET_GETSOCKNAME, and
index 90d2c9caa41675965b4d794e6a630e0732c7fffd..8b1b683d78daff36bf916fc510c9d8317747f778 100644 (file)
@@ -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 \
index 95c9d3fd8a724b521b88a6ab66cfa44062ad0870..e105880a0282e076b0ffb4a9f0cb5fa40732aa1d 100644 (file)
@@ -1,3 +1,13 @@
+2002-12-06  Tom Yu  <tlyu@mit.edu>
+
+       * 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  <tlyu@mit.edu>
 
        * kname_parse.c (kname_unparse): Add new function ported from
index 4f77f2a6ac8b52197aecdb9b95b1cc7cbfb7fc43..1558b65a1486d04ec69e4d74848622d53725229b 100644 (file)
@@ -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;
index 43997a69823109d411b4791cb8bfc76e6574e22b..7ad0534828578285f640fdac1fbb11b1bb543404 100644 (file)
@@ -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;
index 701b975fd298aea394a6e7ea339117aba6e9464f..ce602105d8dd88a1f7831d89685030afbcb6da36 100644 (file)
@@ -13,6 +13,7 @@
 #include "krbports.h"
 #include "prot.h"
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #include <unistd.h>
 #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 <stdlib.h>
-#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);
 }
index 6c57cfbcab4b7b0588151443bc062807f8ef40ab..059fb8913b8551afa01b8d1de39c86e9019b292f 100644 (file)
@@ -1,3 +1,27 @@
+2002-12-06  Tom Yu  <tlyu@mit.edu>
+
+       * 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  <tlyu@mit.edu>
 
        * changepw.c: Remove reference to adm_err.h.
index 400892405daaaaba9cfcb73fdff446d33c87122a..509d317fa3389b8141706b4e87c4e23956617cb4 100644 (file)
@@ -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;
   }
index 17de039bafab8f5764d8a6c68391bf7f1bd1d3d7..60cb3a9158ac89465722b08b2f2f4076f4af1a75 100644 (file)
@@ -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.  */
index 451d3e98244a7d600eef27ca367c913144947458..8dbd553034cc063f35d410dbbd70e67a03135cfd 100644 (file)
@@ -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);
 }
index f474fa04ec10f2c0fa0171e9ca595b8563cd279c..bc26a1dd953ad274d3cf7272a6e7ee1978779c2c 100644 (file)
@@ -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
index 687f4e0793b0a4fce1b4886b62f650711d529f41..300e9777e970b8759a0a6d5bd36cf375aad1db1b 100644 (file)
@@ -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;
index 8365c03a75ff7b6a73113b5f4f3c7f74366a69c1..a3d6828604d76691c8f65b2fbe07ada86f071567 100644 (file)
@@ -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);
index 407d44cabe6b2ea38df6c287103d812945c25197..adaf6893db80d555996d4ec1ac361b85aaa4d731 100644 (file)
@@ -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;