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 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 * 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 ** 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 ** 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 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 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 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 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 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 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 * 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 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