10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
52830Sdjl * Common Development and Distribution License (the "License").
62830Sdjl * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*6812Sraf
220Sstevel@tonic-gate /*
23*6812Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
252830Sdjl */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate * This is the DNS backend for IPv6 addresses.
310Sstevel@tonic-gate * getbyname() is a local routine, but getbyaddr() actually shares the
320Sstevel@tonic-gate * same codes as the one in gethostent.c.
330Sstevel@tonic-gate */
340Sstevel@tonic-gate
350Sstevel@tonic-gate #define endhostent res_endhostent
360Sstevel@tonic-gate
370Sstevel@tonic-gate #include <malloc.h>
380Sstevel@tonic-gate #include <stddef.h>
390Sstevel@tonic-gate #include <string.h>
400Sstevel@tonic-gate #include "dns_common.h"
410Sstevel@tonic-gate
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate * If the DNS name service switch routines are used in a binary that depends
440Sstevel@tonic-gate * on an older libresolv (libresolv.so.1, say), then having nss_dns.so.1 or
450Sstevel@tonic-gate * libnss_dns.a depend on a newer libresolv (libresolv.so.2) will cause
460Sstevel@tonic-gate * relocation problems. In particular, copy relocation of the _res structure
470Sstevel@tonic-gate * (which changes in size from libresolv.so.1 to libresolv.so.2) could
480Sstevel@tonic-gate * cause corruption, and result in a number of strange problems, including
490Sstevel@tonic-gate * core dumps. Hence, we check if a libresolv is already loaded.
500Sstevel@tonic-gate */
510Sstevel@tonic-gate
520Sstevel@tonic-gate
530Sstevel@tonic-gate #pragma weak res_endhostent
540Sstevel@tonic-gate
550Sstevel@tonic-gate extern struct hostent *_gethostbyname(int *, const char *);
560Sstevel@tonic-gate extern struct hostent *_nss_dns_gethostbyname2(int *, const char *);
570Sstevel@tonic-gate
580Sstevel@tonic-gate typedef union {
590Sstevel@tonic-gate long al;
600Sstevel@tonic-gate char ac;
610Sstevel@tonic-gate } align;
620Sstevel@tonic-gate
630Sstevel@tonic-gate
640Sstevel@tonic-gate static void
_endhostent(errp)650Sstevel@tonic-gate _endhostent(errp)
660Sstevel@tonic-gate nss_status_t *errp;
670Sstevel@tonic-gate {
680Sstevel@tonic-gate int ret;
690Sstevel@tonic-gate
700Sstevel@tonic-gate ret = endhostent();
710Sstevel@tonic-gate if (ret == 0)
720Sstevel@tonic-gate *errp = NSS_SUCCESS;
730Sstevel@tonic-gate else
740Sstevel@tonic-gate *errp = NSS_UNAVAIL;
750Sstevel@tonic-gate }
760Sstevel@tonic-gate
770Sstevel@tonic-gate
780Sstevel@tonic-gate #ifdef RNDUP
790Sstevel@tonic-gate #undef RNDUP
800Sstevel@tonic-gate #endif
810Sstevel@tonic-gate #define RNDUP(x) ((1 + (((x)-1)/sizeof (void *))) * sizeof (void *))
820Sstevel@tonic-gate
830Sstevel@tonic-gate #ifdef PTROFF
840Sstevel@tonic-gate #undef PTROFF
850Sstevel@tonic-gate #endif
860Sstevel@tonic-gate #define PTROFF(p, o) (((o) == 0) ? 0 : (void *)((char *)(p) + (o)))
870Sstevel@tonic-gate
880Sstevel@tonic-gate
890Sstevel@tonic-gate /*
900Sstevel@tonic-gate * Make a copy of h->h_name.
910Sstevel@tonic-gate */
920Sstevel@tonic-gate static char *
cloneName(struct hostent * h,int * outerr)930Sstevel@tonic-gate cloneName(struct hostent *h, int *outerr) {
940Sstevel@tonic-gate
950Sstevel@tonic-gate char *name;
960Sstevel@tonic-gate int len;
970Sstevel@tonic-gate int error, *errp;
980Sstevel@tonic-gate
990Sstevel@tonic-gate if (outerr)
1000Sstevel@tonic-gate errp = outerr;
1010Sstevel@tonic-gate else
1020Sstevel@tonic-gate errp = &error;
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate if (h == 0 || h->h_name == 0) {
1050Sstevel@tonic-gate *errp = 0;
1060Sstevel@tonic-gate return (0);
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate len = strlen(h->h_name);
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate if ((name = malloc(len+1)) == 0) {
1120Sstevel@tonic-gate *errp = 1;
1130Sstevel@tonic-gate return (0);
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate
1162830Sdjl (void) memcpy(name, h->h_name, len+1);
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate *errp = 0;
1190Sstevel@tonic-gate return (name);
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate /*
1240Sstevel@tonic-gate * Copy the h->h_addr_list[] array to a new array, and append the
1250Sstevel@tonic-gate * moreAddrs[] list. If h->h_addr_list[] contains IPv4 addresses,
1260Sstevel@tonic-gate * convert them to v4 mapped IPv6 addresses.
1270Sstevel@tonic-gate *
1280Sstevel@tonic-gate * Note: The pointers to the addresses in the moreAddrs[] array are copied,
1290Sstevel@tonic-gate * but not the IP addresses themselves.
1300Sstevel@tonic-gate */
1312830Sdjl static struct in6_addr **
cloneAddrList(struct hostent * h,struct in6_addr ** moreAddrs,int * outerr)1320Sstevel@tonic-gate cloneAddrList(struct hostent *h, struct in6_addr **moreAddrs, int *outerr) {
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate struct in6_addr **addrArray, *addrList;
1350Sstevel@tonic-gate int domap, addrlen, i, j, addrCount, moreAddrCount = 0;
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate int error, *errp;
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate if (outerr)
1400Sstevel@tonic-gate errp = outerr;
1410Sstevel@tonic-gate else
1420Sstevel@tonic-gate errp = &error;
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate if (h == 0 || h->h_addr_list == 0) {
1450Sstevel@tonic-gate *errp = 0;
1460Sstevel@tonic-gate return (0);
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate /* Should we map v4 to IPv6 ? */
1500Sstevel@tonic-gate domap = (h->h_length == sizeof (struct in_addr)) &&
1510Sstevel@tonic-gate (h->h_addrtype == AF_INET);
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate /* If mapping, make sure we allocate enough memory for addresses */
1540Sstevel@tonic-gate addrlen = h->h_length;
1550Sstevel@tonic-gate if (domap && addrlen < sizeof (struct in6_addr))
1560Sstevel@tonic-gate addrlen = sizeof (struct in6_addr);
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate for (addrCount = 0; h->h_addr_list[addrCount]; addrCount++);
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate if (moreAddrs != 0) {
1610Sstevel@tonic-gate for (moreAddrCount = 0; moreAddrs[moreAddrCount];
1620Sstevel@tonic-gate moreAddrCount++);
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate if ((addrArray = malloc((addrCount+moreAddrCount+1)*sizeof (addrList) +
1660Sstevel@tonic-gate addrCount*addrlen)) == 0) {
1670Sstevel@tonic-gate *errp = 1;
1680Sstevel@tonic-gate return (0);
1690Sstevel@tonic-gate }
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate addrList = PTROFF(addrArray, (addrCount+moreAddrCount+1) *
1720Sstevel@tonic-gate sizeof (addrList));
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate for (i = 0; i < addrCount; i++) {
1750Sstevel@tonic-gate addrArray[i] = addrList;
1760Sstevel@tonic-gate if (domap) {
1772830Sdjl /* LINTED: E_BAD_PTR_CAST_ALIGN */
1780Sstevel@tonic-gate IN6_INADDR_TO_V4MAPPED(
1790Sstevel@tonic-gate (struct in_addr *)h->h_addr_list[i], addrArray[i]);
1800Sstevel@tonic-gate } else {
1812830Sdjl (void) memcpy(addrArray[i], h->h_addr_list[i],
1822830Sdjl addrlen);
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate addrList = PTROFF(addrList, addrlen);
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate for (j = 0; j < moreAddrCount; j++, i++) {
1880Sstevel@tonic-gate addrArray[i] = moreAddrs[j];
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate /* Last pointer should be NULL */
1920Sstevel@tonic-gate addrArray[i] = 0;
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate *errp = 0;
1950Sstevel@tonic-gate return (addrArray);
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate
1990Sstevel@tonic-gate /*
2000Sstevel@tonic-gate * Create a new alias array that is is a copy of h->h_aliases[] plus
2010Sstevel@tonic-gate * the aliases in mergeAliases[] which aren't duplicates of any alias
2020Sstevel@tonic-gate * in h->h_aliases[].
2030Sstevel@tonic-gate *
2040Sstevel@tonic-gate * Note 1: Only the string pointers (NOT the strings) in the mergeAliases[]
2050Sstevel@tonic-gate * array are copied.
2060Sstevel@tonic-gate *
2070Sstevel@tonic-gate * Note 2: The duplicate aliases in mergeAliases[] are replaced by NULL
2080Sstevel@tonic-gate * pointers.
2090Sstevel@tonic-gate */
2100Sstevel@tonic-gate static char **
cloneAliasList(struct hostent * h,char ** mergeAliases,int * outerr)2110Sstevel@tonic-gate cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) {
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate char **aliasArray, *aliasList;
2142830Sdjl int i, j, aliasCount, mergeAliasCount = 0, realMac = 0;
2150Sstevel@tonic-gate int stringSize = 0;
2160Sstevel@tonic-gate int error, *errp;
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate if (outerr)
2190Sstevel@tonic-gate errp = outerr;
2200Sstevel@tonic-gate else
2210Sstevel@tonic-gate errp = &error;
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate if (h == 0 || h->h_aliases == 0) {
2250Sstevel@tonic-gate *errp = 0;
2260Sstevel@tonic-gate return (0);
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate for (aliasCount = 0; h->h_aliases[aliasCount]; aliasCount++) {
2300Sstevel@tonic-gate stringSize += RNDUP(strlen(h->h_aliases[aliasCount])+1);
2310Sstevel@tonic-gate }
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate if (mergeAliases != 0) {
2340Sstevel@tonic-gate for (; mergeAliases[mergeAliasCount]; mergeAliasCount++) {
2350Sstevel@tonic-gate int countThis = 1;
2360Sstevel@tonic-gate /* Skip duplicates */
2370Sstevel@tonic-gate for (j = 0; j < aliasCount; j++) {
2380Sstevel@tonic-gate if (strcmp(mergeAliases[mergeAliasCount],
2390Sstevel@tonic-gate h->h_aliases[j]) == 0) {
2400Sstevel@tonic-gate countThis = 0;
2410Sstevel@tonic-gate break;
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate if (countThis)
2450Sstevel@tonic-gate realMac++;
2460Sstevel@tonic-gate else
2470Sstevel@tonic-gate mergeAliases[mergeAliasCount] = 0;
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate if ((aliasArray = malloc((aliasCount+realMac+1)*sizeof (char **)+
2520Sstevel@tonic-gate stringSize)) == 0) {
2530Sstevel@tonic-gate *errp = 1;
2540Sstevel@tonic-gate return (0);
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate
2570Sstevel@tonic-gate aliasList = PTROFF(aliasArray,
2580Sstevel@tonic-gate (aliasCount+realMac+1)*sizeof (char **));
2590Sstevel@tonic-gate for (i = 0; i < aliasCount; i++) {
2600Sstevel@tonic-gate int len = strlen(h->h_aliases[i]);
2610Sstevel@tonic-gate aliasArray[i] = aliasList;
2622830Sdjl (void) memcpy(aliasArray[i], h->h_aliases[i], len+1);
2630Sstevel@tonic-gate aliasList = PTROFF(aliasList, RNDUP(len+1));
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate for (j = 0; j < mergeAliasCount; j++) {
2670Sstevel@tonic-gate if (mergeAliases[j] != 0) {
2680Sstevel@tonic-gate aliasArray[i++] = mergeAliases[j];
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate }
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate aliasArray[i] = 0;
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate *errp = 0;
2750Sstevel@tonic-gate return (aliasArray);
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate
2782830Sdjl /*ARGSUSED*/
2790Sstevel@tonic-gate static nss_status_t
getbyname(be,a)2800Sstevel@tonic-gate getbyname(be, a)
2810Sstevel@tonic-gate dns_backend_ptr_t be;
2820Sstevel@tonic-gate void *a;
2830Sstevel@tonic-gate {
2840Sstevel@tonic-gate struct hostent *he = NULL;
2850Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
2860Sstevel@tonic-gate int ret, mt_disabled;
2870Sstevel@tonic-gate sigset_t oldmask;
2880Sstevel@tonic-gate int converr = 0, gotv6 = 0;
2890Sstevel@tonic-gate struct hostent v6he;
2905161Smichen struct hostent mhe;
2910Sstevel@tonic-gate char *v6Name = 0;
2920Sstevel@tonic-gate struct in6_addr **v6Addrs = 0, **mergeAddrs = 0;
2930Sstevel@tonic-gate char **v6Aliases = 0, **mergeAliases = 0;
2940Sstevel@tonic-gate int v6_h_errno;
2950Sstevel@tonic-gate int old_retry;
2960Sstevel@tonic-gate int af = argp->key.ipnode.af_family;
2970Sstevel@tonic-gate int flags = argp->key.ipnode.flags;
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate switch_resolver_setup(&mt_disabled, &oldmask, &old_retry);
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate /* Now get the AAAA records */
3020Sstevel@tonic-gate if (af == AF_INET6)
3030Sstevel@tonic-gate he = _nss_dns_gethostbyname2(&argp->h_errno,
3040Sstevel@tonic-gate argp->key.ipnode.name);
3050Sstevel@tonic-gate if (he != NULL) {
3060Sstevel@tonic-gate /*
3070Sstevel@tonic-gate * pointer in "he" is part of a static pthread key in libresolv
3080Sstevel@tonic-gate * It should be treated as read only.
3090Sstevel@tonic-gate * So clone a copy first.
3100Sstevel@tonic-gate */
3110Sstevel@tonic-gate v6Name = cloneName(he, &converr);
3120Sstevel@tonic-gate if (converr) {
3130Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND;
3140Sstevel@tonic-gate argp->erange = 1;
3150Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry);
3160Sstevel@tonic-gate return (_herrno2nss(argp->h_errno));
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate v6Addrs = cloneAddrList(he, 0, &converr);
3190Sstevel@tonic-gate if (converr) {
3200Sstevel@tonic-gate if (v6Name != 0)
3210Sstevel@tonic-gate free(v6Name);
3220Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND;
3230Sstevel@tonic-gate argp->erange = 1;
3240Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry);
3250Sstevel@tonic-gate return (_herrno2nss(argp->h_errno));
3260Sstevel@tonic-gate }
3270Sstevel@tonic-gate v6Aliases = cloneAliasList(he, 0, &converr);
3280Sstevel@tonic-gate if (converr) {
3290Sstevel@tonic-gate if (v6Name != 0)
3300Sstevel@tonic-gate free(v6Name);
3310Sstevel@tonic-gate if (v6Addrs != 0)
3320Sstevel@tonic-gate free(v6Addrs);
3330Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND;
3340Sstevel@tonic-gate argp->erange = 1;
3350Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry);
3360Sstevel@tonic-gate return (_herrno2nss(argp->h_errno));
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate v6_h_errno = argp->h_errno;
3390Sstevel@tonic-gate gotv6 = 1;
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate
3420Sstevel@tonic-gate /*
3430Sstevel@tonic-gate * The conditions to search "A" records:
3440Sstevel@tonic-gate * 1. af is AF_INET
3450Sstevel@tonic-gate * 2. if af is AF_INET6
3460Sstevel@tonic-gate * then flags are either
3470Sstevel@tonic-gate * 1) (AI_ALL | AI_V4MAPPED) or
3480Sstevel@tonic-gate * 2) AI_V4MAPPED and he == NULL
3490Sstevel@tonic-gate * (No V6 addresses found or no search for V6 at all)
3500Sstevel@tonic-gate */
3510Sstevel@tonic-gate
3520Sstevel@tonic-gate /* Get the A records, and store the information */
3530Sstevel@tonic-gate if ((af == AF_INET) ||
3540Sstevel@tonic-gate ((af == AF_INET6) &&
3550Sstevel@tonic-gate ((flags & (AI_ALL | AI_V4MAPPED)) ||
3560Sstevel@tonic-gate ((flags & AI_V4MAPPED) && he == NULL))))
3570Sstevel@tonic-gate he = _gethostbyname(&argp->h_errno, argp->key.ipnode.name);
3580Sstevel@tonic-gate else
3590Sstevel@tonic-gate he = NULL;
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate /* Merge the results */
3620Sstevel@tonic-gate if (he != NULL) {
3635161Smichen mhe = *he;
3640Sstevel@tonic-gate mergeAddrs = cloneAddrList(he, v6Addrs, &converr);
3650Sstevel@tonic-gate if (converr) {
3660Sstevel@tonic-gate if (v6Name != 0)
3670Sstevel@tonic-gate free(v6Name);
3680Sstevel@tonic-gate if (v6Addrs != 0)
3690Sstevel@tonic-gate free(v6Addrs);
3700Sstevel@tonic-gate if (v6Aliases != 0)
3710Sstevel@tonic-gate free(v6Aliases);
3720Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND;
3730Sstevel@tonic-gate argp->erange = 1;
3740Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask,
3750Sstevel@tonic-gate old_retry);
3760Sstevel@tonic-gate return (_herrno2nss(argp->h_errno));
3770Sstevel@tonic-gate }
3785161Smichen mhe.h_addr_list = (char **)mergeAddrs;
3790Sstevel@tonic-gate
3800Sstevel@tonic-gate mergeAliases = cloneAliasList(he, v6Aliases, &converr);
3810Sstevel@tonic-gate if (converr) {
3820Sstevel@tonic-gate if (v6Name != 0)
3830Sstevel@tonic-gate free(v6Name);
3840Sstevel@tonic-gate if (v6Addrs != 0)
3850Sstevel@tonic-gate free(v6Addrs);
3860Sstevel@tonic-gate if (v6Aliases != 0)
3870Sstevel@tonic-gate free(v6Aliases);
3880Sstevel@tonic-gate if (mergeAddrs != 0)
3890Sstevel@tonic-gate free(mergeAddrs);
3900Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND;
3910Sstevel@tonic-gate argp->erange = 1;
3920Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask,
3930Sstevel@tonic-gate old_retry);
3940Sstevel@tonic-gate return (_herrno2nss(argp->h_errno));
3950Sstevel@tonic-gate }
3965161Smichen mhe.h_aliases = mergeAliases;
3970Sstevel@tonic-gate
3980Sstevel@tonic-gate /* reset h_length, h_addrtype */
3995161Smichen mhe.h_length = sizeof (struct in6_addr);
4005161Smichen mhe.h_addrtype = AF_INET6;
4015161Smichen he = &mhe;
4020Sstevel@tonic-gate
4030Sstevel@tonic-gate } else if (gotv6) {
4040Sstevel@tonic-gate v6he.h_name = v6Name;
4050Sstevel@tonic-gate v6he.h_length = sizeof (struct in6_addr);
4060Sstevel@tonic-gate v6he.h_addrtype = AF_INET6;
4070Sstevel@tonic-gate v6he.h_addr_list = (char **)v6Addrs;
4080Sstevel@tonic-gate v6he.h_aliases = v6Aliases;
4090Sstevel@tonic-gate he = &v6he;
4100Sstevel@tonic-gate argp->h_errno = v6_h_errno;
4110Sstevel@tonic-gate }
4120Sstevel@tonic-gate
4132830Sdjl if (he != NULL) {
4142830Sdjl /*
4152830Sdjl * if asked to return data in string,
4162830Sdjl * convert the hostent structure into
4172830Sdjl * string data
4182830Sdjl */
4192830Sdjl if (argp->buf.result == NULL) {
4202830Sdjl ret = ent2str(he, a, AF_INET6);
4212830Sdjl if (ret == NSS_STR_PARSE_SUCCESS)
4222830Sdjl argp->returnval = argp->buf.buffer;
4230Sstevel@tonic-gate } else {
4242830Sdjl ret = ent2result(he, a, AF_INET6);
4252830Sdjl if (ret == NSS_STR_PARSE_SUCCESS)
4262830Sdjl argp->returnval = argp->buf.result;
4272830Sdjl }
4282830Sdjl
4292830Sdjl if (ret != NSS_STR_PARSE_SUCCESS) {
4300Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND;
4310Sstevel@tonic-gate if (ret == NSS_STR_PARSE_ERANGE) {
4320Sstevel@tonic-gate argp->erange = 1;
4330Sstevel@tonic-gate }
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate if (v6Name != 0)
4380Sstevel@tonic-gate free(v6Name);
4390Sstevel@tonic-gate if (v6Addrs != 0)
4400Sstevel@tonic-gate free(v6Addrs);
4410Sstevel@tonic-gate if (v6Aliases != 0)
4420Sstevel@tonic-gate free(v6Aliases);
4430Sstevel@tonic-gate if (mergeAddrs != 0)
4440Sstevel@tonic-gate free(mergeAddrs);
4450Sstevel@tonic-gate if (mergeAliases != 0)
4460Sstevel@tonic-gate free(mergeAliases);
4470Sstevel@tonic-gate
4480Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry);
4490Sstevel@tonic-gate
4500Sstevel@tonic-gate return (_herrno2nss(argp->h_errno));
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate
4530Sstevel@tonic-gate
4540Sstevel@tonic-gate extern nss_status_t __nss_dns_getbyaddr(dns_backend_ptr_t, void *);
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate static nss_status_t
getbyaddr(be,a)4570Sstevel@tonic-gate getbyaddr(be, a)
4580Sstevel@tonic-gate dns_backend_ptr_t be;
4590Sstevel@tonic-gate void *a;
4600Sstevel@tonic-gate {
4610Sstevel@tonic-gate /* uses the same getbyaddr from IPv4 */
4620Sstevel@tonic-gate return (__nss_dns_getbyaddr(be, a));
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate /*ARGSUSED*/
4670Sstevel@tonic-gate static nss_status_t
_nss_dns_getent(be,args)4680Sstevel@tonic-gate _nss_dns_getent(be, args)
4690Sstevel@tonic-gate dns_backend_ptr_t be;
4700Sstevel@tonic-gate void *args;
4710Sstevel@tonic-gate {
4720Sstevel@tonic-gate return (NSS_UNAVAIL);
4730Sstevel@tonic-gate }
4740Sstevel@tonic-gate
4750Sstevel@tonic-gate
4760Sstevel@tonic-gate /*ARGSUSED*/
4770Sstevel@tonic-gate static nss_status_t
_nss_dns_setent(be,dummy)4780Sstevel@tonic-gate _nss_dns_setent(be, dummy)
4790Sstevel@tonic-gate dns_backend_ptr_t be;
4800Sstevel@tonic-gate void *dummy;
4810Sstevel@tonic-gate {
4820Sstevel@tonic-gate /* XXXX not implemented at this point */
4830Sstevel@tonic-gate return (NSS_UNAVAIL);
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate /*ARGSUSED*/
4880Sstevel@tonic-gate static nss_status_t
_nss_dns_endent(be,dummy)4890Sstevel@tonic-gate _nss_dns_endent(be, dummy)
4900Sstevel@tonic-gate dns_backend_ptr_t be;
4910Sstevel@tonic-gate void *dummy;
4920Sstevel@tonic-gate {
4930Sstevel@tonic-gate /* XXXX not implemented at this point */
4940Sstevel@tonic-gate return (NSS_UNAVAIL);
4950Sstevel@tonic-gate }
4960Sstevel@tonic-gate
4970Sstevel@tonic-gate
4980Sstevel@tonic-gate /*ARGSUSED*/
4990Sstevel@tonic-gate static nss_status_t
_nss_dns_destr(be,dummy)5000Sstevel@tonic-gate _nss_dns_destr(be, dummy)
5010Sstevel@tonic-gate dns_backend_ptr_t be;
5020Sstevel@tonic-gate void *dummy;
5030Sstevel@tonic-gate {
5040Sstevel@tonic-gate nss_status_t errp;
5050Sstevel@tonic-gate
5060Sstevel@tonic-gate if (be != 0) {
5070Sstevel@tonic-gate /* === Should change to invoke ops[ENDENT] ? */
5080Sstevel@tonic-gate sigset_t oldmask, newmask;
5090Sstevel@tonic-gate int mt_disabled = 1;
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) {
5120Sstevel@tonic-gate (void) sigfillset(&newmask);
513*6812Sraf (void) thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask);
514*6812Sraf (void) mutex_lock(&one_lane);
5150Sstevel@tonic-gate }
5160Sstevel@tonic-gate
5170Sstevel@tonic-gate _endhostent(&errp);
5180Sstevel@tonic-gate
5190Sstevel@tonic-gate if (mt_disabled) {
520*6812Sraf (void) mutex_unlock(&one_lane);
521*6812Sraf (void) thr_sigsetmask(SIG_SETMASK, &oldmask, NULL);
5220Sstevel@tonic-gate } else {
5230Sstevel@tonic-gate (void) (*disable_mt)();
5240Sstevel@tonic-gate }
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate free(be);
5270Sstevel@tonic-gate }
5280Sstevel@tonic-gate return (NSS_SUCCESS); /* In case anyone is dumb enough to check */
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate static dns_backend_op_t ipnodes_ops[] = {
5340Sstevel@tonic-gate _nss_dns_destr,
5350Sstevel@tonic-gate _nss_dns_endent,
5360Sstevel@tonic-gate _nss_dns_setent,
5370Sstevel@tonic-gate _nss_dns_getent,
5380Sstevel@tonic-gate getbyname,
5390Sstevel@tonic-gate getbyaddr,
5400Sstevel@tonic-gate };
5410Sstevel@tonic-gate
5420Sstevel@tonic-gate /*ARGSUSED*/
5430Sstevel@tonic-gate nss_backend_t *
_nss_dns_ipnodes_constr(dummy1,dummy2,dummy3)5440Sstevel@tonic-gate _nss_dns_ipnodes_constr(dummy1, dummy2, dummy3)
5450Sstevel@tonic-gate const char *dummy1, *dummy2, *dummy3;
5460Sstevel@tonic-gate {
5470Sstevel@tonic-gate return (_nss_dns_constr(ipnodes_ops,
5480Sstevel@tonic-gate sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0])));
5490Sstevel@tonic-gate }
5502830Sdjl
5512830Sdjl /*
5522830Sdjl * optional NSS2 packed backend gethostsbyipnode with ttl
5532830Sdjl * entry point.
5542830Sdjl *
5552830Sdjl * Returns:
5562830Sdjl * NSS_SUCCESS - successful
5572830Sdjl * NSS_NOTFOUND - successful but nothing found
5582830Sdjl * NSS_ERROR - fallback to NSS backend lookup mode
5592830Sdjl * If successful, buffer will be filled with valid data
5602830Sdjl *
5612830Sdjl */
5622830Sdjl
5632830Sdjl /*ARGSUSED*/
5642830Sdjl nss_status_t
_nss_get_dns_ipnodes_name(dns_backend_ptr_t * be,void ** bufp,size_t * sizep)5652830Sdjl _nss_get_dns_ipnodes_name(dns_backend_ptr_t *be, void **bufp, size_t *sizep)
5662830Sdjl {
5672830Sdjl return (_nss_dns_gethost_withttl(*bufp, *sizep, 1));
5682830Sdjl }
569