xref: /onnv-gate/usr/src/lib/gss_mechs/mech_krb5/krb5/os/hostaddr.c (revision 13132:9615cdbf7b70)
1*13132SGlenn.Barry@oracle.com /*
2*13132SGlenn.Barry@oracle.com  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3*13132SGlenn.Barry@oracle.com  */
40Sstevel@tonic-gate /*
50Sstevel@tonic-gate  * lib/krb5/os/hostaddr.c
60Sstevel@tonic-gate  *
70Sstevel@tonic-gate  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
80Sstevel@tonic-gate  * All Rights Reserved.
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  * Export of this software from the United States of America may
110Sstevel@tonic-gate  *   require a specific license from the United States Government.
120Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
130Sstevel@tonic-gate  *   export to obtain such a license before exporting.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
160Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
170Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
180Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
190Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
200Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
210Sstevel@tonic-gate  * to distribution of the software without specific, written prior
220Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
230Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
240Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
250Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
260Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
270Sstevel@tonic-gate  * or implied warranty.
280Sstevel@tonic-gate  *
290Sstevel@tonic-gate  * This routine returns a list of krb5 addresses given a hostname.
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  */
320Sstevel@tonic-gate 
337934SMark.Phalan@Sun.COM #include "k5-int.h"
34*13132SGlenn.Barry@oracle.com #include <locale.h>
357934SMark.Phalan@Sun.COM #include "fake-addrinfo.h"
360Sstevel@tonic-gate 
370Sstevel@tonic-gate krb5_error_code
krb5_os_hostaddr(krb5_context context,const char * name,krb5_address *** ret_addrs)387934SMark.Phalan@Sun.COM krb5_os_hostaddr(krb5_context context, const char *name, krb5_address ***ret_addrs)
390Sstevel@tonic-gate {
400Sstevel@tonic-gate     krb5_error_code 	retval;
410Sstevel@tonic-gate     krb5_address 	**addrs;
420Sstevel@tonic-gate     int			i, j, r;
430Sstevel@tonic-gate     struct addrinfo hints, *ai, *aip;
440Sstevel@tonic-gate 
45*13132SGlenn.Barry@oracle.com     if (!name) {
460Sstevel@tonic-gate 	return KRB5_ERR_BAD_HOSTNAME;
47*13132SGlenn.Barry@oracle.com     }
480Sstevel@tonic-gate 
490Sstevel@tonic-gate     memset (&hints, 0, sizeof (hints));
500Sstevel@tonic-gate     hints.ai_flags = AI_NUMERICHOST;
510Sstevel@tonic-gate     /* We don't care what kind at this point, really, but without
520Sstevel@tonic-gate        this, we can get back multiple sockaddrs per address, for
530Sstevel@tonic-gate        SOCK_DGRAM, SOCK_STREAM, and SOCK_RAW.  I haven't checked if
540Sstevel@tonic-gate        that's what the spec indicates.  */
550Sstevel@tonic-gate     hints.ai_socktype = SOCK_DGRAM;
560Sstevel@tonic-gate 
570Sstevel@tonic-gate     r = getaddrinfo (name, 0, &hints, &ai);
580Sstevel@tonic-gate     if (r && AI_NUMERICHOST != 0) {
590Sstevel@tonic-gate 	hints.ai_flags &= ~AI_NUMERICHOST;
600Sstevel@tonic-gate 	r = getaddrinfo (name, 0, &hints, &ai);
610Sstevel@tonic-gate     }
62*13132SGlenn.Barry@oracle.com     if (r) {
63*13132SGlenn.Barry@oracle.com         krb5_set_error_message(context, KRB5_ERR_BAD_HOSTNAME,
64*13132SGlenn.Barry@oracle.com 			    dgettext(TEXT_DOMAIN,
65*13132SGlenn.Barry@oracle.com 				    "Hostname cannot be canonicalized for '%s': %s"),
66*13132SGlenn.Barry@oracle.com 			    name, strerror(r));
670Sstevel@tonic-gate 	return KRB5_ERR_BAD_HOSTNAME;
68*13132SGlenn.Barry@oracle.com     }
690Sstevel@tonic-gate 
700Sstevel@tonic-gate     for (i = 0, aip = ai; aip; aip = aip->ai_next) {
710Sstevel@tonic-gate 	switch (aip->ai_addr->sa_family) {
720Sstevel@tonic-gate 	case AF_INET:
730Sstevel@tonic-gate #ifdef KRB5_USE_INET6
740Sstevel@tonic-gate 	case AF_INET6:
750Sstevel@tonic-gate #endif
760Sstevel@tonic-gate 	    i++;
770Sstevel@tonic-gate 	default:
780Sstevel@tonic-gate 	    /* Ignore addresses of unknown families.  */
790Sstevel@tonic-gate 	    ;
800Sstevel@tonic-gate 	}
810Sstevel@tonic-gate     }
820Sstevel@tonic-gate 
830Sstevel@tonic-gate     addrs = malloc ((i+1) * sizeof(*addrs));
840Sstevel@tonic-gate     if (!addrs)
850Sstevel@tonic-gate 	return errno;
860Sstevel@tonic-gate 
870Sstevel@tonic-gate     for (j = 0; j < i + 1; j++)
880Sstevel@tonic-gate 	addrs[j] = 0;
890Sstevel@tonic-gate 
900Sstevel@tonic-gate     for (i = 0, aip = ai; aip; aip = aip->ai_next) {
910Sstevel@tonic-gate 	void *ptr;
920Sstevel@tonic-gate 	size_t addrlen;
930Sstevel@tonic-gate 	int atype;
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	switch (aip->ai_addr->sa_family) {
960Sstevel@tonic-gate 	case AF_INET:
970Sstevel@tonic-gate 	    addrlen = sizeof (struct in_addr);
980Sstevel@tonic-gate 	    /*LINTED*/
990Sstevel@tonic-gate 	    ptr = &sa2sin(aip->ai_addr)->sin_addr;
1000Sstevel@tonic-gate 	    atype = ADDRTYPE_INET;
1010Sstevel@tonic-gate 	    break;
1020Sstevel@tonic-gate #ifdef KRB5_USE_INET6
1030Sstevel@tonic-gate 	case AF_INET6:
1040Sstevel@tonic-gate 	    addrlen = sizeof (struct in6_addr);
1050Sstevel@tonic-gate 	    /*LINTED*/
1060Sstevel@tonic-gate 	    ptr = &sa2sin6(aip->ai_addr)->sin6_addr;
1070Sstevel@tonic-gate 	    atype = ADDRTYPE_INET6;
1080Sstevel@tonic-gate 	    break;
1090Sstevel@tonic-gate #endif
1100Sstevel@tonic-gate 	default:
1110Sstevel@tonic-gate 	    continue;
1120Sstevel@tonic-gate 	}
1130Sstevel@tonic-gate 	addrs[i] = (krb5_address *) malloc(sizeof(krb5_address));
1140Sstevel@tonic-gate 	if (!addrs[i]) {
1150Sstevel@tonic-gate 	    retval = ENOMEM;
1160Sstevel@tonic-gate 	    goto errout;
1170Sstevel@tonic-gate 	}
1180Sstevel@tonic-gate 	addrs[i]->magic = KV5M_ADDRESS;
1190Sstevel@tonic-gate 	addrs[i]->addrtype = atype;
1200Sstevel@tonic-gate 	addrs[i]->length = addrlen;
1210Sstevel@tonic-gate 	addrs[i]->contents = malloc(addrs[i]->length);
1220Sstevel@tonic-gate 	if (!addrs[i]->contents) {
1230Sstevel@tonic-gate 	    retval = ENOMEM;
1240Sstevel@tonic-gate 	    goto errout;
1250Sstevel@tonic-gate 	}
1260Sstevel@tonic-gate 	memcpy (addrs[i]->contents, ptr, addrs[i]->length);
1270Sstevel@tonic-gate 	i++;
1280Sstevel@tonic-gate     }
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate     *ret_addrs = addrs;
1310Sstevel@tonic-gate     if (ai)
1320Sstevel@tonic-gate 	freeaddrinfo(ai);
1330Sstevel@tonic-gate     return 0;
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate errout:
13612366SMark.Phalan@Sun.COM     /* Solaris Kerberos */
13712366SMark.Phalan@Sun.COM     if (addrs)
1380Sstevel@tonic-gate 	krb5_free_addresses(context, addrs);
1390Sstevel@tonic-gate     if (ai)
1400Sstevel@tonic-gate 	freeaddrinfo(ai);
1410Sstevel@tonic-gate     return retval;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate 
145