15e01956fSGlenn Barry /*
25e01956fSGlenn Barry * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
35e01956fSGlenn Barry */
47c478bd9Sstevel@tonic-gate /*
57c478bd9Sstevel@tonic-gate * lib/krb5/os/hostaddr.c
67c478bd9Sstevel@tonic-gate *
77c478bd9Sstevel@tonic-gate * Copyright 1990,1991 by the Massachusetts Institute of Technology.
87c478bd9Sstevel@tonic-gate * All Rights Reserved.
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
117c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
127c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
137c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
14*55fea89dSDan Cross *
157c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
167c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
177c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
187c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
197c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
207c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
217c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
227c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
237c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
247c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
257c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
267c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
277c478bd9Sstevel@tonic-gate * or implied warranty.
28*55fea89dSDan Cross *
297c478bd9Sstevel@tonic-gate * This routine returns a list of krb5 addresses given a hostname.
307c478bd9Sstevel@tonic-gate *
317c478bd9Sstevel@tonic-gate */
327c478bd9Sstevel@tonic-gate
33159d09a2SMark Phalan #include "k5-int.h"
345e01956fSGlenn Barry #include <locale.h>
35159d09a2SMark Phalan #include "fake-addrinfo.h"
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate krb5_error_code
krb5_os_hostaddr(krb5_context context,const char * name,krb5_address *** ret_addrs)38159d09a2SMark Phalan krb5_os_hostaddr(krb5_context context, const char *name, krb5_address ***ret_addrs)
397c478bd9Sstevel@tonic-gate {
407c478bd9Sstevel@tonic-gate krb5_error_code retval;
417c478bd9Sstevel@tonic-gate krb5_address **addrs;
427c478bd9Sstevel@tonic-gate int i, j, r;
437c478bd9Sstevel@tonic-gate struct addrinfo hints, *ai, *aip;
447c478bd9Sstevel@tonic-gate
455e01956fSGlenn Barry if (!name) {
467c478bd9Sstevel@tonic-gate return KRB5_ERR_BAD_HOSTNAME;
475e01956fSGlenn Barry }
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate memset (&hints, 0, sizeof (hints));
507c478bd9Sstevel@tonic-gate hints.ai_flags = AI_NUMERICHOST;
517c478bd9Sstevel@tonic-gate /* We don't care what kind at this point, really, but without
527c478bd9Sstevel@tonic-gate this, we can get back multiple sockaddrs per address, for
537c478bd9Sstevel@tonic-gate SOCK_DGRAM, SOCK_STREAM, and SOCK_RAW. I haven't checked if
547c478bd9Sstevel@tonic-gate that's what the spec indicates. */
557c478bd9Sstevel@tonic-gate hints.ai_socktype = SOCK_DGRAM;
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate r = getaddrinfo (name, 0, &hints, &ai);
587c478bd9Sstevel@tonic-gate if (r && AI_NUMERICHOST != 0) {
597c478bd9Sstevel@tonic-gate hints.ai_flags &= ~AI_NUMERICHOST;
607c478bd9Sstevel@tonic-gate r = getaddrinfo (name, 0, &hints, &ai);
617c478bd9Sstevel@tonic-gate }
625e01956fSGlenn Barry if (r) {
635e01956fSGlenn Barry krb5_set_error_message(context, KRB5_ERR_BAD_HOSTNAME,
645e01956fSGlenn Barry dgettext(TEXT_DOMAIN,
655e01956fSGlenn Barry "Hostname cannot be canonicalized for '%s': %s"),
665e01956fSGlenn Barry name, strerror(r));
677c478bd9Sstevel@tonic-gate return KRB5_ERR_BAD_HOSTNAME;
685e01956fSGlenn Barry }
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate for (i = 0, aip = ai; aip; aip = aip->ai_next) {
717c478bd9Sstevel@tonic-gate switch (aip->ai_addr->sa_family) {
727c478bd9Sstevel@tonic-gate case AF_INET:
737c478bd9Sstevel@tonic-gate #ifdef KRB5_USE_INET6
747c478bd9Sstevel@tonic-gate case AF_INET6:
757c478bd9Sstevel@tonic-gate #endif
767c478bd9Sstevel@tonic-gate i++;
777c478bd9Sstevel@tonic-gate default:
787c478bd9Sstevel@tonic-gate /* Ignore addresses of unknown families. */
797c478bd9Sstevel@tonic-gate ;
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate }
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate addrs = malloc ((i+1) * sizeof(*addrs));
847c478bd9Sstevel@tonic-gate if (!addrs)
857c478bd9Sstevel@tonic-gate return errno;
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate for (j = 0; j < i + 1; j++)
887c478bd9Sstevel@tonic-gate addrs[j] = 0;
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate for (i = 0, aip = ai; aip; aip = aip->ai_next) {
917c478bd9Sstevel@tonic-gate void *ptr;
927c478bd9Sstevel@tonic-gate size_t addrlen;
937c478bd9Sstevel@tonic-gate int atype;
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate switch (aip->ai_addr->sa_family) {
967c478bd9Sstevel@tonic-gate case AF_INET:
977c478bd9Sstevel@tonic-gate addrlen = sizeof (struct in_addr);
987c478bd9Sstevel@tonic-gate /*LINTED*/
997c478bd9Sstevel@tonic-gate ptr = &sa2sin(aip->ai_addr)->sin_addr;
1007c478bd9Sstevel@tonic-gate atype = ADDRTYPE_INET;
1017c478bd9Sstevel@tonic-gate break;
1027c478bd9Sstevel@tonic-gate #ifdef KRB5_USE_INET6
1037c478bd9Sstevel@tonic-gate case AF_INET6:
1047c478bd9Sstevel@tonic-gate addrlen = sizeof (struct in6_addr);
1057c478bd9Sstevel@tonic-gate /*LINTED*/
1067c478bd9Sstevel@tonic-gate ptr = &sa2sin6(aip->ai_addr)->sin6_addr;
1077c478bd9Sstevel@tonic-gate atype = ADDRTYPE_INET6;
1087c478bd9Sstevel@tonic-gate break;
1097c478bd9Sstevel@tonic-gate #endif
1107c478bd9Sstevel@tonic-gate default:
1117c478bd9Sstevel@tonic-gate continue;
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate addrs[i] = (krb5_address *) malloc(sizeof(krb5_address));
1147c478bd9Sstevel@tonic-gate if (!addrs[i]) {
1157c478bd9Sstevel@tonic-gate retval = ENOMEM;
1167c478bd9Sstevel@tonic-gate goto errout;
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate addrs[i]->magic = KV5M_ADDRESS;
1197c478bd9Sstevel@tonic-gate addrs[i]->addrtype = atype;
1207c478bd9Sstevel@tonic-gate addrs[i]->length = addrlen;
1217c478bd9Sstevel@tonic-gate addrs[i]->contents = malloc(addrs[i]->length);
1227c478bd9Sstevel@tonic-gate if (!addrs[i]->contents) {
1237c478bd9Sstevel@tonic-gate retval = ENOMEM;
1247c478bd9Sstevel@tonic-gate goto errout;
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate memcpy (addrs[i]->contents, ptr, addrs[i]->length);
1277c478bd9Sstevel@tonic-gate i++;
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate *ret_addrs = addrs;
1317c478bd9Sstevel@tonic-gate if (ai)
1327c478bd9Sstevel@tonic-gate freeaddrinfo(ai);
1337c478bd9Sstevel@tonic-gate return 0;
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate errout:
13635ea52c6SMark Phalan /* Solaris Kerberos */
13735ea52c6SMark Phalan if (addrs)
1387c478bd9Sstevel@tonic-gate krb5_free_addresses(context, addrs);
1397c478bd9Sstevel@tonic-gate if (ai)
1407c478bd9Sstevel@tonic-gate freeaddrinfo(ai);
1417c478bd9Sstevel@tonic-gate return retval;
142*55fea89dSDan Cross
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate
145