Split out code for getting canonical name of local host, change it to use
authorKen Raeburn <raeburn@mit.edu>
Wed, 9 Jan 2002 03:56:32 +0000 (03:56 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 9 Jan 2002 03:56:32 +0000 (03:56 +0000)
getaddrinfo, and make both sites call the new function.  Added new error codes
to report getaddrinfo failures that don't translate to standard errno codes.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14100 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/error_tables/krb5_err.et
src/lib/krb5/os/ChangeLog
src/lib/krb5/os/def_realm.c
src/lib/krb5/os/hst_realm.c

index 6135a9dfa82db682c8a6a9d2da4d677d51102d84..a7ff6eaf1a10dd583b5897a31e62a903a0314b78 100644 (file)
@@ -323,4 +323,10 @@ error_code KRB5_NOPERM_ETYPE,      "Encryption type not permitted"
 error_code KRB5_CONFIG_ETYPE_NOSUPP,   "No supported encryption types (config file error?)"
 error_code KRB5_OBSOLETE_FN,   "Program called an obsolete, deleted function"
 
+# translated versions of getaddrinfo errors
+error_code KRB5_EAI_FAIL,      "unknown getaddrinfo failure"
+error_code KRB5_EAI_NODATA,    "no data available for host/domain name"
+error_code KRB5_EAI_NONAME,    "host/domain name not found"
+error_code KRB5_EAI_SERVICE,   "service name unknown"
+
 end
index a5914451d04922560999de74661f05cf09716839..603c0ab04fbfd25da4cb451b1122d555312c32c3 100644 (file)
@@ -1,3 +1,11 @@
+2002-01-08  Ken Raeburn  <raeburn@mit.edu>
+
+       * hst_realm.c (krb5int_get_fq_hostname): New function.  Use
+       getaddrinfo instead of gethostbyname.
+       (krb5int_get_fq_local_hostname): New function.
+       (krb5_get_host_realm): Call it.
+       * def_realm.c (krb5_get_default_realm): Call it.
+
 2001-12-05  Ezra Peisach  <epeisach@mit.edu>
 
        * sendto_kdc.c (krb5_sendto_kdc): Get rid of unecessary casts.
index 9b9ca49b46f40de7bc2fb37e629868a1d9bb859c..0f0a40ad8e03c1d98a80ff180467d9a1279da431 100644 (file)
@@ -119,26 +119,10 @@ krb5_get_default_realm(context, lrealm)
                 */
                char localhost[MAX_DNS_NAMELEN+1];
                char * p;
-               struct hostent * h;
 
-               localhost[0] = 0;
-               gethostname(localhost, sizeof(localhost));
-               localhost[sizeof(localhost) - 1] = 0;
+               krb5int_get_fq_local_hostname (localhost, sizeof(localhost));
 
                if ( localhost[0] ) {
-                   /*
-                    * Try to make sure that we have a fully qualified
-                    * name if possible.  We want to be able to handle
-                    * the case where gethostname returns a partial
-                    * name (i.e., it has a dot, but it is not a
-                    * FQDN).
-                    */
-                   h = gethostbyname(localhost);
-                   if (h) {
-                       strncpy(localhost, h->h_name, sizeof(localhost));
-                       localhost[sizeof(localhost) - 1] = '\0';
-                   }
-
                    p = localhost;
                    do {
                        retval = krb5_try_realm_txt_rr("_kerberos", p, 
@@ -147,7 +131,7 @@ krb5_get_default_realm(context, lrealm)
                        if (p)
                            p++;
                    } while (retval && p && p[0]);
-                   
+
                    if (retval)
                        retval = krb5_try_realm_txt_rr("_kerberos", "", 
                                                       &context->default_realm);
index c973ba3f4f03ea83e1f454a93a2c721fae9bf9e5..568178f76d7fc377e013a2070c53ea6e0db4abaa 100644 (file)
@@ -90,6 +90,9 @@
 #endif /* WSHELPER */
 #endif /* KRB5_DNS_LOOKUP */ 
 
+#define FAI_PREFIX krb5int
+#include "fake-addrinfo.h"
+
 /* for old Unixes and friends ... */
 #ifndef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN 64
@@ -231,6 +234,39 @@ krb5_try_realm_txt_rr(prefix, name, realm)
 }
 #endif /* KRB5_DNS_LOOKUP */
 
+krb5_error_code krb5int_translate_gai_error (int);
+
+static krb5_error_code
+krb5int_get_fq_hostname (char *buf, size_t bufsize, const char *name)
+{
+    struct addrinfo *ai, hints;
+    int err;
+
+    memset (&hints, 0, sizeof (hints));
+    hints.ai_flags = AI_CANONNAME;
+    err = getaddrinfo (name, 0, &hints, &ai);
+    if (err)
+       return krb5int_translate_gai_error (err);
+    if (ai->ai_canonname == 0)
+       return KRB5_EAI_FAIL;
+    strncpy (buf, ai->ai_canonname, bufsize);
+    buf[bufsize-1] = 0;
+    freeaddrinfo (ai);
+    return 0;
+}
+
+/* Get the local host name, try to make it fully-qualified.
+   Always return a null-terminated string.
+   Might return an error if gethostname fails.  */
+krb5_error_code
+krb5int_get_fq_local_hostname (char *buf, size_t bufsiz)
+{
+    buf[0] = 0;
+    if (gethostname (buf, bufsiz) == -1)
+       return SOCKET_ERRNO;
+    buf[bufsiz - 1] = 0;
+    return krb5int_get_fq_hostname (buf, bufsiz, buf);
+}
 
 krb5_error_code KRB5_CALLCONV
 krb5_get_host_realm(context, host, realmsp)
@@ -243,25 +279,17 @@ krb5_get_host_realm(context, host, realmsp)
     krb5_error_code retval;
     int l;
     char local_host[MAX_DNS_NAMELEN+1];
-    struct hostent *h;
 
-
-    if (host)
+    if (host) {
+       /* Should probably error out if strlen(host) > MAX_DNS_NAMELEN.  */
        strncpy(local_host, host, sizeof(local_host));
-    else {
-       if (gethostname(local_host, sizeof(local_host)) == -1)
-           return SOCKET_ERRNO;
-       /*
-        * Try to make sure that we have a fully qualified name if
-        * possible.  We need to handle the case where the host has a
-        * dot but is not FQDN, so we call gethostbyname.
-        */
-       h = gethostbyname(local_host);
-       if (h) {
-           strncpy(local_host, h->h_name, sizeof(local_host));
-       }
+       local_host[sizeof(local_host) - 1] = '\0';
+    } else {
+       retval = krb5int_get_fq_local_hostname (local_host,
+                                               sizeof (local_host));
+       if (retval)
+           return retval;
     }
-    local_host[sizeof(local_host) - 1] = '\0';
 
     for (cp = local_host; *cp; cp++) {
        if (isupper((int) (*cp)))
@@ -369,3 +397,35 @@ krb5_get_host_realm(context, host, realmsp)
     *realmsp = retrealms;
     return 0;
 }
+
+
+krb5_error_code
+krb5int_translate_gai_error (int num)
+{
+    switch (num) {
+    case EAI_ADDRFAMILY:
+       return EAFNOSUPPORT;
+    case EAI_AGAIN:
+       return EAGAIN;
+    case EAI_BADFLAGS:
+       return EINVAL;
+    case EAI_FAIL:
+       return KRB5_EAI_FAIL;
+    case EAI_FAMILY:
+       return EAFNOSUPPORT;
+    case EAI_MEMORY:
+       return ENOMEM;
+    case EAI_NODATA:
+       return KRB5_EAI_NODATA;
+    case EAI_NONAME:
+       return KRB5_EAI_NONAME;
+    case EAI_SERVICE:
+       return KRB5_EAI_SERVICE;
+    case EAI_SOCKTYPE:
+       return EINVAL;
+    case EAI_SYSTEM:
+       return errno;
+    }
+    abort ();
+    return -1;
+}