17c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27c478bd9Sstevel@tonic-gate 
37c478bd9Sstevel@tonic-gate /*
47c478bd9Sstevel@tonic-gate  * lib/krb5/os/hst_realm.c
57c478bd9Sstevel@tonic-gate  *
67c478bd9Sstevel@tonic-gate  * Copyright 1990,1991,2002 by the Massachusetts Institute of Technology.
77c478bd9Sstevel@tonic-gate  * All Rights Reserved.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
107c478bd9Sstevel@tonic-gate  *   require a specific license from the United States Government.
117c478bd9Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
127c478bd9Sstevel@tonic-gate  *   export to obtain such a license before exporting.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
157c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
167c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
177c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
187c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
197c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
207c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
217c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
227c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
237c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
247c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
257c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
267c478bd9Sstevel@tonic-gate  * or implied warranty.
277c478bd9Sstevel@tonic-gate  *
287c478bd9Sstevel@tonic-gate  *
297c478bd9Sstevel@tonic-gate  * krb5_get_host_realm()
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate /*
347c478bd9Sstevel@tonic-gate  Figures out the Kerberos realm names for host, filling in a
357c478bd9Sstevel@tonic-gate  pointer to an argv[] style list of names, terminated with a null pointer.
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate  If host is NULL, the local host's realms are determined.
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate  If there are no known realms for the host, the filled-in pointer is set
407c478bd9Sstevel@tonic-gate  to NULL.
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate  The pointer array and strings pointed to are all in allocated storage,
437c478bd9Sstevel@tonic-gate  and should be freed by the caller when finished.
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate  returns system errors
467c478bd9Sstevel@tonic-gate */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate  * Implementation notes:
507c478bd9Sstevel@tonic-gate  *
517c478bd9Sstevel@tonic-gate  * this implementation only provides one realm per host, using the same
527c478bd9Sstevel@tonic-gate  * mapping file used in kerberos v4.
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate  * Given a fully-qualified domain-style primary host name,
557c478bd9Sstevel@tonic-gate  * return the name of the Kerberos realm for the host.
567c478bd9Sstevel@tonic-gate  * If the hostname contains no discernable domain, or an error occurs,
577c478bd9Sstevel@tonic-gate  * return the local realm name, as supplied by krb5_get_default_realm().
587c478bd9Sstevel@tonic-gate  * If the hostname contains a domain, but no translation is found,
597c478bd9Sstevel@tonic-gate  * the hostname's domain is converted to upper-case and returned.
607c478bd9Sstevel@tonic-gate  *
617c478bd9Sstevel@tonic-gate  * The format of each line of the translation file is:
627c478bd9Sstevel@tonic-gate  * domain_name kerberos_realm
637c478bd9Sstevel@tonic-gate  * -or-
647c478bd9Sstevel@tonic-gate  * host_name kerberos_realm
657c478bd9Sstevel@tonic-gate  *
667c478bd9Sstevel@tonic-gate  * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
677c478bd9Sstevel@tonic-gate  * host names should be in the usual form (e.g. FOO.BAR.BAZ)
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate #define NEED_SOCKETS
717c478bd9Sstevel@tonic-gate #include "k5-int.h"
727c478bd9Sstevel@tonic-gate #include "os-proto.h"
737c478bd9Sstevel@tonic-gate #include <ctype.h>
747c478bd9Sstevel@tonic-gate #include <stdio.h>
757c478bd9Sstevel@tonic-gate #ifdef HAVE_STRING_H
767c478bd9Sstevel@tonic-gate #include <string.h>
777c478bd9Sstevel@tonic-gate #else
787c478bd9Sstevel@tonic-gate #include <strings.h>
797c478bd9Sstevel@tonic-gate #endif
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
827c478bd9Sstevel@tonic-gate #ifdef WSHELPER
837c478bd9Sstevel@tonic-gate #include <wshelper.h>
847c478bd9Sstevel@tonic-gate #else /* WSHELPER */
857c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
867c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
877c478bd9Sstevel@tonic-gate #ifndef T_TXT /* not defined on SunOS 4 */
887c478bd9Sstevel@tonic-gate #  define T_TXT 15
897c478bd9Sstevel@tonic-gate #endif
907c478bd9Sstevel@tonic-gate #include <resolv.h>
917c478bd9Sstevel@tonic-gate #include <netdb.h>
927c478bd9Sstevel@tonic-gate #endif /* WSHELPER */
937c478bd9Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate #include <fake-addrinfo.h>
967c478bd9Sstevel@tonic-gate 
97*505d05c7Sgtb #ifdef KRB5_DNS_LOOKUP
987c478bd9Sstevel@tonic-gate 
99*505d05c7Sgtb #include "dnsglue.h"
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate  * Try to look up a TXT record pointing to a Kerberos realm
1037c478bd9Sstevel@tonic-gate  */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate krb5_error_code
1067c478bd9Sstevel@tonic-gate krb5_try_realm_txt_rr(const char *prefix, const char *name, char **realm)
1077c478bd9Sstevel@tonic-gate {
108*505d05c7Sgtb     krb5_error_code retval = KRB5_ERR_HOST_REALM_UNKNOWN;
109*505d05c7Sgtb     const unsigned char *p, *base;
110*505d05c7Sgtb     char host[MAXDNAME], *h;
111*505d05c7Sgtb     int ret, rdlen, len;
112*505d05c7Sgtb     struct krb5int_dns_state *ds = NULL;
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate     /*
1157c478bd9Sstevel@tonic-gate      * Form our query, and send it via DNS
1167c478bd9Sstevel@tonic-gate      */
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate     if (name == NULL || name[0] == '\0') {
1197c478bd9Sstevel@tonic-gate 	if (strlen (prefix) >= sizeof(host)-1)
1207c478bd9Sstevel@tonic-gate 	    return KRB5_ERR_HOST_REALM_UNKNOWN;
1217c478bd9Sstevel@tonic-gate         strcpy(host,prefix);
1227c478bd9Sstevel@tonic-gate     } else {
123*505d05c7Sgtb         if ( strlen(prefix) + strlen(name) + 3 > MAXDNAME )
1247c478bd9Sstevel@tonic-gate             return KRB5_ERR_HOST_REALM_UNKNOWN;
1257c478bd9Sstevel@tonic-gate 	/*LINTED*/
1267c478bd9Sstevel@tonic-gate         sprintf(host,"%s.%s", prefix, name);
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate         /* Realm names don't (normally) end with ".", but if the query
1297c478bd9Sstevel@tonic-gate            doesn't end with "." and doesn't get an answer as is, the
1307c478bd9Sstevel@tonic-gate            resolv code will try appending the local domain.  Since the
1317c478bd9Sstevel@tonic-gate            realm names are absolutes, let's stop that.
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate            But only if a name has been specified.  If we are performing
1347c478bd9Sstevel@tonic-gate            a search on the prefix alone then the intention is to allow
1357c478bd9Sstevel@tonic-gate            the local domain or domain search lists to be expanded.
1367c478bd9Sstevel@tonic-gate         */
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate         h = host + strlen (host);
1397c478bd9Sstevel@tonic-gate         if ((h > host) && (h[-1] != '.') && ((h - host + 1) < sizeof(host)))
1407c478bd9Sstevel@tonic-gate             strcpy (h, ".");
1417c478bd9Sstevel@tonic-gate     }
142*505d05c7Sgtb     ret = krb5int_dns_init(&ds, host, C_IN, T_TXT);
143*505d05c7Sgtb     if (ret < 0)
144*505d05c7Sgtb       goto errout;
145*505d05c7Sgtb 
146*505d05c7Sgtb     ret = krb5int_dns_nextans(ds, &base, &rdlen);
147*505d05c7Sgtb     if (ret < 0 || base == NULL)
148*505d05c7Sgtb       goto errout;
149*505d05c7Sgtb 
150*505d05c7Sgtb     p = base;
151*505d05c7Sgtb     if (!INCR_OK(base, rdlen, p, 1))
152*505d05c7Sgtb       goto errout;
153*505d05c7Sgtb 
154*505d05c7Sgtb     len = *p++;
155*505d05c7Sgtb     *realm = malloc((size_t)len + 1);
156*505d05c7Sgtb     if (*realm == NULL) {
157*505d05c7Sgtb       retval = ENOMEM;
158*505d05c7Sgtb       goto errout;
1597c478bd9Sstevel@tonic-gate     }
160*505d05c7Sgtb     strncpy(*realm, (const char *)p, (size_t)len);
161*505d05c7Sgtb     (*realm)[len] = '\0';
162*505d05c7Sgtb     /* Avoid a common error. */
163*505d05c7Sgtb     if ( (*realm)[len-1] == '.' )
164*505d05c7Sgtb       (*realm)[len-1] = '\0';
165*505d05c7Sgtb     retval = 0;
166*505d05c7Sgtb 
167*505d05c7Sgtb errout:
168*505d05c7Sgtb     if (ds != NULL) {
169*505d05c7Sgtb       krb5int_dns_fini(ds);
170*505d05c7Sgtb       ds = NULL;
1717c478bd9Sstevel@tonic-gate     }
172*505d05c7Sgtb     return retval;
1737c478bd9Sstevel@tonic-gate }
174*505d05c7Sgtb #else /* KRB5_DNS_LOOKUP */
175*505d05c7Sgtb #ifndef MAXDNAME
176*505d05c7Sgtb #define MAXDNAME (16 * MAXHOSTNAMELEN)
177*505d05c7Sgtb #endif /* MAXDNAME */
1787c478bd9Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
1797c478bd9Sstevel@tonic-gate 
180*505d05c7Sgtb 
1817c478bd9Sstevel@tonic-gate krb5_error_code krb5int_translate_gai_error (int);
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate static krb5_error_code
1847c478bd9Sstevel@tonic-gate krb5int_get_fq_hostname (char *buf, size_t bufsize, const char *name)
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate     struct addrinfo *ai, hints;
1877c478bd9Sstevel@tonic-gate     int err;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate     memset (&hints, 0, sizeof (hints));
1907c478bd9Sstevel@tonic-gate     hints.ai_family = AF_UNSPEC;
1917c478bd9Sstevel@tonic-gate     hints.ai_flags = AI_CANONNAME;
1927c478bd9Sstevel@tonic-gate     err = getaddrinfo (name, 0, &hints, &ai);
1937c478bd9Sstevel@tonic-gate     if (err)
1947c478bd9Sstevel@tonic-gate 	return krb5int_translate_gai_error (err);
1957c478bd9Sstevel@tonic-gate     if (ai->ai_canonname == 0)
1967c478bd9Sstevel@tonic-gate 	return KRB5_EAI_FAIL;
1977c478bd9Sstevel@tonic-gate     strncpy (buf, ai->ai_canonname, bufsize);
1987c478bd9Sstevel@tonic-gate     buf[bufsize-1] = 0;
1997c478bd9Sstevel@tonic-gate     freeaddrinfo (ai);
2007c478bd9Sstevel@tonic-gate     return 0;
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate /* Get the local host name, try to make it fully-qualified.
2047c478bd9Sstevel@tonic-gate    Always return a null-terminated string.
2057c478bd9Sstevel@tonic-gate    Might return an error if gethostname fails.  */
2067c478bd9Sstevel@tonic-gate krb5_error_code
2077c478bd9Sstevel@tonic-gate krb5int_get_fq_local_hostname (char *buf, size_t bufsiz)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate     buf[0] = 0;
2107c478bd9Sstevel@tonic-gate     if (gethostname (buf, bufsiz) == -1)
2117c478bd9Sstevel@tonic-gate 	return SOCKET_ERRNO;
2127c478bd9Sstevel@tonic-gate     buf[bufsiz - 1] = 0;
2137c478bd9Sstevel@tonic-gate     return krb5int_get_fq_hostname (buf, bufsiz, buf);
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate krb5_error_code KRB5_CALLCONV
2177c478bd9Sstevel@tonic-gate krb5_get_host_realm(krb5_context context, const char *host, char ***realmsp)
2187c478bd9Sstevel@tonic-gate {
2197c478bd9Sstevel@tonic-gate     char **retrealms;
2207c478bd9Sstevel@tonic-gate     char *default_realm, *realm, *cp, *temp_realm;
2217c478bd9Sstevel@tonic-gate     krb5_error_code retval;
2227c478bd9Sstevel@tonic-gate     int l;
223*505d05c7Sgtb     char local_host[MAXDNAME+1];
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate     if (host) {
2267c478bd9Sstevel@tonic-gate 	/* Filter out numeric addresses if the caller utterly failed to
2277c478bd9Sstevel@tonic-gate 	   convert them to names.  */
2287c478bd9Sstevel@tonic-gate 	/* IPv4 - dotted quads only */
2297c478bd9Sstevel@tonic-gate 	if (strspn(host, "01234567890.") == strlen(host)) {
2307c478bd9Sstevel@tonic-gate 	    /* All numbers and dots... if it's three dots, it's an
2317c478bd9Sstevel@tonic-gate 	       IP address, and we reject it.  But "12345" could be
2327c478bd9Sstevel@tonic-gate 	       a local hostname, couldn't it?  We'll just assume
2337c478bd9Sstevel@tonic-gate 	       that a name with three dots is not meant to be an
2347c478bd9Sstevel@tonic-gate 	       all-numeric hostname three all-numeric domains down
2357c478bd9Sstevel@tonic-gate 	       from the current domain.  */
2367c478bd9Sstevel@tonic-gate 	    int ndots = 0;
2377c478bd9Sstevel@tonic-gate 	    const char *p;
2387c478bd9Sstevel@tonic-gate 	    for (p = host; *p; p++)
2397c478bd9Sstevel@tonic-gate 		if (*p == '.')
2407c478bd9Sstevel@tonic-gate 		    ndots++;
2417c478bd9Sstevel@tonic-gate 	    if (ndots == 3)
2427c478bd9Sstevel@tonic-gate 		return KRB5_ERR_NUMERIC_REALM;
2437c478bd9Sstevel@tonic-gate 	}
2447c478bd9Sstevel@tonic-gate 	if (strchr(host, ':'))
2457c478bd9Sstevel@tonic-gate 	    /* IPv6 numeric address form?  Bye bye.  */
2467c478bd9Sstevel@tonic-gate 	    return KRB5_ERR_NUMERIC_REALM;
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 	/* Should probably error out if strlen(host) > MAX_DNS_NAMELEN.  */
2497c478bd9Sstevel@tonic-gate 	strncpy(local_host, host, sizeof(local_host));
2507c478bd9Sstevel@tonic-gate 	local_host[sizeof(local_host) - 1] = '\0';
2517c478bd9Sstevel@tonic-gate     } else {
2527c478bd9Sstevel@tonic-gate 	retval = krb5int_get_fq_local_hostname (local_host,
2537c478bd9Sstevel@tonic-gate 						sizeof (local_host));
2547c478bd9Sstevel@tonic-gate 	if (retval)
2557c478bd9Sstevel@tonic-gate 	    return retval;
2567c478bd9Sstevel@tonic-gate     }
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate     for (cp = local_host; *cp; cp++) {
2597c478bd9Sstevel@tonic-gate 	if (isupper((int) (*cp)))
2607c478bd9Sstevel@tonic-gate 	    *cp = tolower((int) *cp);
2617c478bd9Sstevel@tonic-gate     }
2627c478bd9Sstevel@tonic-gate     l = strlen(local_host);
2637c478bd9Sstevel@tonic-gate     /* strip off trailing dot */
2647c478bd9Sstevel@tonic-gate     if (l && local_host[l-1] == '.')
2657c478bd9Sstevel@tonic-gate 	    local_host[l-1] = 0;
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate     /*
2687c478bd9Sstevel@tonic-gate        Search for the best match for the host or domain.
2697c478bd9Sstevel@tonic-gate        Example: Given a host a.b.c.d, try to match on:
2707c478bd9Sstevel@tonic-gate          1) A.B.C.D
2717c478bd9Sstevel@tonic-gate 	 2) .B.C.D
2727c478bd9Sstevel@tonic-gate 	 3) B.C.D
2737c478bd9Sstevel@tonic-gate 	 4) .C.D
2747c478bd9Sstevel@tonic-gate 	 5) C.D
2757c478bd9Sstevel@tonic-gate 	 6) .D
2767c478bd9Sstevel@tonic-gate 	 7) D
2777c478bd9Sstevel@tonic-gate      */
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate     cp = local_host;
2807c478bd9Sstevel@tonic-gate     realm = default_realm = (char *)NULL;
2817c478bd9Sstevel@tonic-gate     temp_realm = 0;
2827c478bd9Sstevel@tonic-gate     while (cp) {
2837c478bd9Sstevel@tonic-gate 	retval = profile_get_string(context->profile, "domain_realm", cp,
2847c478bd9Sstevel@tonic-gate 				    0, (char *)NULL, &temp_realm);
2857c478bd9Sstevel@tonic-gate 	if (retval)
2867c478bd9Sstevel@tonic-gate 	    return retval;
2877c478bd9Sstevel@tonic-gate 	if (temp_realm != (char *)NULL)
2887c478bd9Sstevel@tonic-gate 	    break;	/* Match found */
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	/* Setup for another test */
2917c478bd9Sstevel@tonic-gate 	if (*cp == '.') {
2927c478bd9Sstevel@tonic-gate 	    cp++;
2937c478bd9Sstevel@tonic-gate 	    if (default_realm == (char *)NULL) {
2947c478bd9Sstevel@tonic-gate 		/* If nothing else works, use the host's domain */
2957c478bd9Sstevel@tonic-gate 		default_realm = cp;
2967c478bd9Sstevel@tonic-gate 	    }
2977c478bd9Sstevel@tonic-gate 	} else {
2987c478bd9Sstevel@tonic-gate 	    cp = strchr(cp, '.');
2997c478bd9Sstevel@tonic-gate 	}
3007c478bd9Sstevel@tonic-gate     }
3017c478bd9Sstevel@tonic-gate     if (temp_realm) {
3027c478bd9Sstevel@tonic-gate         realm = malloc(strlen(temp_realm) + 1);
3037c478bd9Sstevel@tonic-gate         if (!realm) {
3047c478bd9Sstevel@tonic-gate             profile_release_string(temp_realm);
3057c478bd9Sstevel@tonic-gate             return ENOMEM;
3067c478bd9Sstevel@tonic-gate         }
3077c478bd9Sstevel@tonic-gate         strcpy(realm, temp_realm);
3087c478bd9Sstevel@tonic-gate         profile_release_string(temp_realm);
3097c478bd9Sstevel@tonic-gate     }
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate #ifdef KRB5_DNS_LOOKUP
3127c478bd9Sstevel@tonic-gate     if (realm == (char *)NULL) {
3137c478bd9Sstevel@tonic-gate         int use_dns = _krb5_use_dns_realm(context);
3147c478bd9Sstevel@tonic-gate         if ( use_dns ) {
3157c478bd9Sstevel@tonic-gate             /*
3167c478bd9Sstevel@tonic-gate              * Since this didn't appear in our config file, try looking
3177c478bd9Sstevel@tonic-gate              * it up via DNS.  Look for a TXT records of the form:
3187c478bd9Sstevel@tonic-gate              *
3197c478bd9Sstevel@tonic-gate              * _kerberos.<hostname>
3207c478bd9Sstevel@tonic-gate              *
3217c478bd9Sstevel@tonic-gate              */
3227c478bd9Sstevel@tonic-gate             cp = local_host;
3237c478bd9Sstevel@tonic-gate             do {
3247c478bd9Sstevel@tonic-gate                 retval = krb5_try_realm_txt_rr("_kerberos", cp, &realm);
3257c478bd9Sstevel@tonic-gate                 cp = strchr(cp,'.');
3267c478bd9Sstevel@tonic-gate                 if (cp)
3277c478bd9Sstevel@tonic-gate                     cp++;
3287c478bd9Sstevel@tonic-gate             } while (retval && cp && cp[0]);
3297c478bd9Sstevel@tonic-gate         }
3307c478bd9Sstevel@tonic-gate     }
3317c478bd9Sstevel@tonic-gate #endif /* KRB5_DNS_LOOKUP */
3327c478bd9Sstevel@tonic-gate     if (realm == (char *)NULL) {
3337c478bd9Sstevel@tonic-gate         if (default_realm != (char *)NULL) {
3347c478bd9Sstevel@tonic-gate             /* We are defaulting to the realm of the host */
3357c478bd9Sstevel@tonic-gate             if (!(cp = (char *)malloc(strlen(default_realm)+1)))
3367c478bd9Sstevel@tonic-gate                 return ENOMEM;
3377c478bd9Sstevel@tonic-gate             strcpy(cp, default_realm);
3387c478bd9Sstevel@tonic-gate             realm = cp;
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate             /* Assume the realm name is upper case */
3417c478bd9Sstevel@tonic-gate             for (cp = realm; *cp; cp++)
3427c478bd9Sstevel@tonic-gate                 if (islower((int) (*cp)))
3437c478bd9Sstevel@tonic-gate                     *cp = toupper((int) *cp);
3447c478bd9Sstevel@tonic-gate         } else {
3457c478bd9Sstevel@tonic-gate             /* We are defaulting to the local realm */
3467c478bd9Sstevel@tonic-gate             retval = krb5_get_default_realm(context, &realm);
3477c478bd9Sstevel@tonic-gate             if (retval) {
3487c478bd9Sstevel@tonic-gate                 return retval;
3497c478bd9Sstevel@tonic-gate             }
3507c478bd9Sstevel@tonic-gate         }
3517c478bd9Sstevel@tonic-gate     }
3527c478bd9Sstevel@tonic-gate     if (!(retrealms = (char **)calloc(2, sizeof(*retrealms)))) {
3537c478bd9Sstevel@tonic-gate 	if (realm != (char *)NULL)
3547c478bd9Sstevel@tonic-gate 	    free(realm);
3557c478bd9Sstevel@tonic-gate 	return ENOMEM;
3567c478bd9Sstevel@tonic-gate     }
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate     retrealms[0] = realm;
3597c478bd9Sstevel@tonic-gate     retrealms[1] = 0;
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate     *realmsp = retrealms;
3627c478bd9Sstevel@tonic-gate     return 0;
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate #if defined(_WIN32) && !defined(__CYGWIN32__)
3667c478bd9Sstevel@tonic-gate # ifndef EAFNOSUPPORT
3677c478bd9Sstevel@tonic-gate #  define EAFNOSUPPORT WSAEAFNOSUPPORT
3687c478bd9Sstevel@tonic-gate # endif
3697c478bd9Sstevel@tonic-gate #endif
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate krb5_error_code
3727c478bd9Sstevel@tonic-gate krb5int_translate_gai_error (int num)
3737c478bd9Sstevel@tonic-gate {
3747c478bd9Sstevel@tonic-gate     switch (num) {
3757c478bd9Sstevel@tonic-gate #ifdef EAI_ADDRFAMILY
3767c478bd9Sstevel@tonic-gate     case EAI_ADDRFAMILY:
3777c478bd9Sstevel@tonic-gate 	return EAFNOSUPPORT;
3787c478bd9Sstevel@tonic-gate #endif
3797c478bd9Sstevel@tonic-gate     case EAI_AGAIN:
3807c478bd9Sstevel@tonic-gate 	return EAGAIN;
3817c478bd9Sstevel@tonic-gate     case EAI_BADFLAGS:
3827c478bd9Sstevel@tonic-gate 	return EINVAL;
3837c478bd9Sstevel@tonic-gate     case EAI_FAIL:
3847c478bd9Sstevel@tonic-gate 	return KRB5_EAI_FAIL;
3857c478bd9Sstevel@tonic-gate     case EAI_FAMILY:
3867c478bd9Sstevel@tonic-gate 	return EAFNOSUPPORT;
3877c478bd9Sstevel@tonic-gate     case EAI_MEMORY:
3887c478bd9Sstevel@tonic-gate 	return ENOMEM;
3897c478bd9Sstevel@tonic-gate #if EAI_NODATA != EAI_NONAME
3907c478bd9Sstevel@tonic-gate     case EAI_NODATA:
3917c478bd9Sstevel@tonic-gate 	return KRB5_EAI_NODATA;
3927c478bd9Sstevel@tonic-gate #endif
3937c478bd9Sstevel@tonic-gate     case EAI_NONAME:
3947c478bd9Sstevel@tonic-gate 	return KRB5_EAI_NONAME;
3957c478bd9Sstevel@tonic-gate     case EAI_SERVICE:
3967c478bd9Sstevel@tonic-gate 	return KRB5_EAI_SERVICE;
3977c478bd9Sstevel@tonic-gate     case EAI_SOCKTYPE:
3987c478bd9Sstevel@tonic-gate 	return EINVAL;
3997c478bd9Sstevel@tonic-gate #ifdef EAI_SYSTEM
4007c478bd9Sstevel@tonic-gate     case EAI_SYSTEM:
4017c478bd9Sstevel@tonic-gate 	return errno;
4027c478bd9Sstevel@tonic-gate #endif
4037c478bd9Sstevel@tonic-gate     }
4047c478bd9Sstevel@tonic-gate     /* abort (); */
4057c478bd9Sstevel@tonic-gate     return -1;
4067c478bd9Sstevel@tonic-gate }
407