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 5*2830Sdjl * Common Development and Distribution License (the "License"). 6*2830Sdjl * 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 */ 210Sstevel@tonic-gate /* 22*2830Sdjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 24*2830Sdjl */ 25*2830Sdjl /* 260Sstevel@tonic-gate * gethostent6.c 270Sstevel@tonic-gate */ 280Sstevel@tonic-gate 290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 310Sstevel@tonic-gate /* 320Sstevel@tonic-gate * This is the DNS backend for IPv6 addresses. 330Sstevel@tonic-gate * getbyname() is a local routine, but getbyaddr() actually shares the 340Sstevel@tonic-gate * same codes as the one in gethostent.c. 350Sstevel@tonic-gate */ 360Sstevel@tonic-gate 370Sstevel@tonic-gate #define endhostent res_endhostent 380Sstevel@tonic-gate 390Sstevel@tonic-gate #include <malloc.h> 400Sstevel@tonic-gate #include <stddef.h> 410Sstevel@tonic-gate #include <string.h> 420Sstevel@tonic-gate #include "dns_common.h" 430Sstevel@tonic-gate 440Sstevel@tonic-gate /* 450Sstevel@tonic-gate * If the DNS name service switch routines are used in a binary that depends 460Sstevel@tonic-gate * on an older libresolv (libresolv.so.1, say), then having nss_dns.so.1 or 470Sstevel@tonic-gate * libnss_dns.a depend on a newer libresolv (libresolv.so.2) will cause 480Sstevel@tonic-gate * relocation problems. In particular, copy relocation of the _res structure 490Sstevel@tonic-gate * (which changes in size from libresolv.so.1 to libresolv.so.2) could 500Sstevel@tonic-gate * cause corruption, and result in a number of strange problems, including 510Sstevel@tonic-gate * core dumps. Hence, we check if a libresolv is already loaded. 520Sstevel@tonic-gate */ 530Sstevel@tonic-gate 540Sstevel@tonic-gate 550Sstevel@tonic-gate #pragma weak res_endhostent 560Sstevel@tonic-gate 570Sstevel@tonic-gate extern struct hostent *_gethostbyname(int *, const char *); 580Sstevel@tonic-gate extern struct hostent *_nss_dns_gethostbyname2(int *, const char *); 590Sstevel@tonic-gate 600Sstevel@tonic-gate typedef union { 610Sstevel@tonic-gate long al; 620Sstevel@tonic-gate char ac; 630Sstevel@tonic-gate } align; 640Sstevel@tonic-gate 650Sstevel@tonic-gate 660Sstevel@tonic-gate static void 670Sstevel@tonic-gate _endhostent(errp) 680Sstevel@tonic-gate nss_status_t *errp; 690Sstevel@tonic-gate { 700Sstevel@tonic-gate int ret; 710Sstevel@tonic-gate 720Sstevel@tonic-gate ret = endhostent(); 730Sstevel@tonic-gate if (ret == 0) 740Sstevel@tonic-gate *errp = NSS_SUCCESS; 750Sstevel@tonic-gate else 760Sstevel@tonic-gate *errp = NSS_UNAVAIL; 770Sstevel@tonic-gate } 780Sstevel@tonic-gate 790Sstevel@tonic-gate 800Sstevel@tonic-gate #ifdef RNDUP 810Sstevel@tonic-gate #undef RNDUP 820Sstevel@tonic-gate #endif 830Sstevel@tonic-gate #define RNDUP(x) ((1 + (((x)-1)/sizeof (void *))) * sizeof (void *)) 840Sstevel@tonic-gate 850Sstevel@tonic-gate #ifdef PTROFF 860Sstevel@tonic-gate #undef PTROFF 870Sstevel@tonic-gate #endif 880Sstevel@tonic-gate #define PTROFF(p, o) (((o) == 0) ? 0 : (void *)((char *)(p) + (o))) 890Sstevel@tonic-gate 900Sstevel@tonic-gate 910Sstevel@tonic-gate /* 920Sstevel@tonic-gate * Make a copy of h->h_name. 930Sstevel@tonic-gate */ 940Sstevel@tonic-gate static char * 950Sstevel@tonic-gate cloneName(struct hostent *h, int *outerr) { 960Sstevel@tonic-gate 970Sstevel@tonic-gate char *name; 980Sstevel@tonic-gate int len; 990Sstevel@tonic-gate int error, *errp; 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate if (outerr) 1020Sstevel@tonic-gate errp = outerr; 1030Sstevel@tonic-gate else 1040Sstevel@tonic-gate errp = &error; 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate if (h == 0 || h->h_name == 0) { 1070Sstevel@tonic-gate *errp = 0; 1080Sstevel@tonic-gate return (0); 1090Sstevel@tonic-gate } 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate len = strlen(h->h_name); 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate if ((name = malloc(len+1)) == 0) { 1140Sstevel@tonic-gate *errp = 1; 1150Sstevel@tonic-gate return (0); 1160Sstevel@tonic-gate } 1170Sstevel@tonic-gate 118*2830Sdjl (void) memcpy(name, h->h_name, len+1); 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate *errp = 0; 1210Sstevel@tonic-gate return (name); 1220Sstevel@tonic-gate } 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate /* 1260Sstevel@tonic-gate * Copy the h->h_addr_list[] array to a new array, and append the 1270Sstevel@tonic-gate * moreAddrs[] list. If h->h_addr_list[] contains IPv4 addresses, 1280Sstevel@tonic-gate * convert them to v4 mapped IPv6 addresses. 1290Sstevel@tonic-gate * 1300Sstevel@tonic-gate * Note: The pointers to the addresses in the moreAddrs[] array are copied, 1310Sstevel@tonic-gate * but not the IP addresses themselves. 1320Sstevel@tonic-gate */ 133*2830Sdjl static struct in6_addr ** 1340Sstevel@tonic-gate cloneAddrList(struct hostent *h, struct in6_addr **moreAddrs, int *outerr) { 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate struct in6_addr **addrArray, *addrList; 1370Sstevel@tonic-gate int domap, addrlen, i, j, addrCount, moreAddrCount = 0; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate int error, *errp; 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate if (outerr) 1420Sstevel@tonic-gate errp = outerr; 1430Sstevel@tonic-gate else 1440Sstevel@tonic-gate errp = &error; 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate if (h == 0 || h->h_addr_list == 0) { 1470Sstevel@tonic-gate *errp = 0; 1480Sstevel@tonic-gate return (0); 1490Sstevel@tonic-gate } 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate /* Should we map v4 to IPv6 ? */ 1520Sstevel@tonic-gate domap = (h->h_length == sizeof (struct in_addr)) && 1530Sstevel@tonic-gate (h->h_addrtype == AF_INET); 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate /* If mapping, make sure we allocate enough memory for addresses */ 1560Sstevel@tonic-gate addrlen = h->h_length; 1570Sstevel@tonic-gate if (domap && addrlen < sizeof (struct in6_addr)) 1580Sstevel@tonic-gate addrlen = sizeof (struct in6_addr); 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate for (addrCount = 0; h->h_addr_list[addrCount]; addrCount++); 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate if (moreAddrs != 0) { 1630Sstevel@tonic-gate for (moreAddrCount = 0; moreAddrs[moreAddrCount]; 1640Sstevel@tonic-gate moreAddrCount++); 1650Sstevel@tonic-gate } 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate if ((addrArray = malloc((addrCount+moreAddrCount+1)*sizeof (addrList) + 1680Sstevel@tonic-gate addrCount*addrlen)) == 0) { 1690Sstevel@tonic-gate *errp = 1; 1700Sstevel@tonic-gate return (0); 1710Sstevel@tonic-gate } 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate addrList = PTROFF(addrArray, (addrCount+moreAddrCount+1) * 1740Sstevel@tonic-gate sizeof (addrList)); 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate for (i = 0; i < addrCount; i++) { 1770Sstevel@tonic-gate addrArray[i] = addrList; 1780Sstevel@tonic-gate if (domap) { 179*2830Sdjl /* LINTED: E_BAD_PTR_CAST_ALIGN */ 1800Sstevel@tonic-gate IN6_INADDR_TO_V4MAPPED( 1810Sstevel@tonic-gate (struct in_addr *)h->h_addr_list[i], addrArray[i]); 1820Sstevel@tonic-gate } else { 183*2830Sdjl (void) memcpy(addrArray[i], h->h_addr_list[i], 184*2830Sdjl addrlen); 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate addrList = PTROFF(addrList, addrlen); 1870Sstevel@tonic-gate } 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate for (j = 0; j < moreAddrCount; j++, i++) { 1900Sstevel@tonic-gate addrArray[i] = moreAddrs[j]; 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate /* Last pointer should be NULL */ 1940Sstevel@tonic-gate addrArray[i] = 0; 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate *errp = 0; 1970Sstevel@tonic-gate return (addrArray); 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate /* 2020Sstevel@tonic-gate * Create a new alias array that is is a copy of h->h_aliases[] plus 2030Sstevel@tonic-gate * the aliases in mergeAliases[] which aren't duplicates of any alias 2040Sstevel@tonic-gate * in h->h_aliases[]. 2050Sstevel@tonic-gate * 2060Sstevel@tonic-gate * Note 1: Only the string pointers (NOT the strings) in the mergeAliases[] 2070Sstevel@tonic-gate * array are copied. 2080Sstevel@tonic-gate * 2090Sstevel@tonic-gate * Note 2: The duplicate aliases in mergeAliases[] are replaced by NULL 2100Sstevel@tonic-gate * pointers. 2110Sstevel@tonic-gate */ 2120Sstevel@tonic-gate static char ** 2130Sstevel@tonic-gate cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) { 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate char **aliasArray, *aliasList; 216*2830Sdjl int i, j, aliasCount, mergeAliasCount = 0, realMac = 0; 2170Sstevel@tonic-gate int stringSize = 0; 2180Sstevel@tonic-gate int error, *errp; 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate if (outerr) 2210Sstevel@tonic-gate errp = outerr; 2220Sstevel@tonic-gate else 2230Sstevel@tonic-gate errp = &error; 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate if (h == 0 || h->h_aliases == 0) { 2270Sstevel@tonic-gate *errp = 0; 2280Sstevel@tonic-gate return (0); 2290Sstevel@tonic-gate } 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate for (aliasCount = 0; h->h_aliases[aliasCount]; aliasCount++) { 2320Sstevel@tonic-gate stringSize += RNDUP(strlen(h->h_aliases[aliasCount])+1); 2330Sstevel@tonic-gate } 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate if (mergeAliases != 0) { 2360Sstevel@tonic-gate for (; mergeAliases[mergeAliasCount]; mergeAliasCount++) { 2370Sstevel@tonic-gate int countThis = 1; 2380Sstevel@tonic-gate /* Skip duplicates */ 2390Sstevel@tonic-gate for (j = 0; j < aliasCount; j++) { 2400Sstevel@tonic-gate if (strcmp(mergeAliases[mergeAliasCount], 2410Sstevel@tonic-gate h->h_aliases[j]) == 0) { 2420Sstevel@tonic-gate countThis = 0; 2430Sstevel@tonic-gate break; 2440Sstevel@tonic-gate } 2450Sstevel@tonic-gate } 2460Sstevel@tonic-gate if (countThis) 2470Sstevel@tonic-gate realMac++; 2480Sstevel@tonic-gate else 2490Sstevel@tonic-gate mergeAliases[mergeAliasCount] = 0; 2500Sstevel@tonic-gate } 2510Sstevel@tonic-gate } 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate if ((aliasArray = malloc((aliasCount+realMac+1)*sizeof (char **)+ 2540Sstevel@tonic-gate stringSize)) == 0) { 2550Sstevel@tonic-gate *errp = 1; 2560Sstevel@tonic-gate return (0); 2570Sstevel@tonic-gate } 2580Sstevel@tonic-gate 2590Sstevel@tonic-gate aliasList = PTROFF(aliasArray, 2600Sstevel@tonic-gate (aliasCount+realMac+1)*sizeof (char **)); 2610Sstevel@tonic-gate for (i = 0; i < aliasCount; i++) { 2620Sstevel@tonic-gate int len = strlen(h->h_aliases[i]); 2630Sstevel@tonic-gate aliasArray[i] = aliasList; 264*2830Sdjl (void) memcpy(aliasArray[i], h->h_aliases[i], len+1); 2650Sstevel@tonic-gate aliasList = PTROFF(aliasList, RNDUP(len+1)); 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate for (j = 0; j < mergeAliasCount; j++) { 2690Sstevel@tonic-gate if (mergeAliases[j] != 0) { 2700Sstevel@tonic-gate aliasArray[i++] = mergeAliases[j]; 2710Sstevel@tonic-gate } 2720Sstevel@tonic-gate } 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate aliasArray[i] = 0; 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate *errp = 0; 2770Sstevel@tonic-gate return (aliasArray); 2780Sstevel@tonic-gate } 2790Sstevel@tonic-gate 280*2830Sdjl /*ARGSUSED*/ 2810Sstevel@tonic-gate static nss_status_t 2820Sstevel@tonic-gate getbyname(be, a) 2830Sstevel@tonic-gate dns_backend_ptr_t be; 2840Sstevel@tonic-gate void *a; 2850Sstevel@tonic-gate { 2860Sstevel@tonic-gate struct hostent *he = NULL; 2870Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 2880Sstevel@tonic-gate int ret, mt_disabled; 2890Sstevel@tonic-gate sigset_t oldmask; 2900Sstevel@tonic-gate int converr = 0, gotv6 = 0; 2910Sstevel@tonic-gate struct hostent v6he; 2920Sstevel@tonic-gate char *v6Name = 0; 2930Sstevel@tonic-gate struct in6_addr **v6Addrs = 0, **mergeAddrs = 0; 2940Sstevel@tonic-gate char **v6Aliases = 0, **mergeAliases = 0; 2950Sstevel@tonic-gate int v6_h_errno; 2960Sstevel@tonic-gate int old_retry; 2970Sstevel@tonic-gate int af = argp->key.ipnode.af_family; 2980Sstevel@tonic-gate int flags = argp->key.ipnode.flags; 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate switch_resolver_setup(&mt_disabled, &oldmask, &old_retry); 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate /* Now get the AAAA records */ 3030Sstevel@tonic-gate if (af == AF_INET6) 3040Sstevel@tonic-gate he = _nss_dns_gethostbyname2(&argp->h_errno, 3050Sstevel@tonic-gate argp->key.ipnode.name); 3060Sstevel@tonic-gate if (he != NULL) { 3070Sstevel@tonic-gate /* 3080Sstevel@tonic-gate * pointer in "he" is part of a static pthread key in libresolv 3090Sstevel@tonic-gate * It should be treated as read only. 3100Sstevel@tonic-gate * So clone a copy first. 3110Sstevel@tonic-gate */ 3120Sstevel@tonic-gate v6Name = cloneName(he, &converr); 3130Sstevel@tonic-gate if (converr) { 3140Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 3150Sstevel@tonic-gate argp->erange = 1; 3160Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry); 3170Sstevel@tonic-gate return (_herrno2nss(argp->h_errno)); 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate v6Addrs = cloneAddrList(he, 0, &converr); 3200Sstevel@tonic-gate if (converr) { 3210Sstevel@tonic-gate if (v6Name != 0) 3220Sstevel@tonic-gate free(v6Name); 3230Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 3240Sstevel@tonic-gate argp->erange = 1; 3250Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry); 3260Sstevel@tonic-gate return (_herrno2nss(argp->h_errno)); 3270Sstevel@tonic-gate } 3280Sstevel@tonic-gate v6Aliases = cloneAliasList(he, 0, &converr); 3290Sstevel@tonic-gate if (converr) { 3300Sstevel@tonic-gate if (v6Name != 0) 3310Sstevel@tonic-gate free(v6Name); 3320Sstevel@tonic-gate if (v6Addrs != 0) 3330Sstevel@tonic-gate free(v6Addrs); 3340Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 3350Sstevel@tonic-gate argp->erange = 1; 3360Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry); 3370Sstevel@tonic-gate return (_herrno2nss(argp->h_errno)); 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate v6_h_errno = argp->h_errno; 3400Sstevel@tonic-gate gotv6 = 1; 3410Sstevel@tonic-gate } 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate /* 3440Sstevel@tonic-gate * The conditions to search "A" records: 3450Sstevel@tonic-gate * 1. af is AF_INET 3460Sstevel@tonic-gate * 2. if af is AF_INET6 3470Sstevel@tonic-gate * then flags are either 3480Sstevel@tonic-gate * 1) (AI_ALL | AI_V4MAPPED) or 3490Sstevel@tonic-gate * 2) AI_V4MAPPED and he == NULL 3500Sstevel@tonic-gate * (No V6 addresses found or no search for V6 at all) 3510Sstevel@tonic-gate */ 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate /* Get the A records, and store the information */ 3540Sstevel@tonic-gate if ((af == AF_INET) || 3550Sstevel@tonic-gate ((af == AF_INET6) && 3560Sstevel@tonic-gate ((flags & (AI_ALL | AI_V4MAPPED)) || 3570Sstevel@tonic-gate ((flags & AI_V4MAPPED) && he == NULL)))) 3580Sstevel@tonic-gate he = _gethostbyname(&argp->h_errno, argp->key.ipnode.name); 3590Sstevel@tonic-gate else 3600Sstevel@tonic-gate he = NULL; 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate /* Merge the results */ 3630Sstevel@tonic-gate if (he != NULL) { 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 } 3780Sstevel@tonic-gate he->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 } 3960Sstevel@tonic-gate he->h_aliases = mergeAliases; 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate /* reset h_length, h_addrtype */ 3990Sstevel@tonic-gate he->h_length = sizeof (struct in6_addr); 4000Sstevel@tonic-gate he->h_addrtype = AF_INET6; 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate } else if (gotv6) { 4030Sstevel@tonic-gate v6he.h_name = v6Name; 4040Sstevel@tonic-gate v6he.h_length = sizeof (struct in6_addr); 4050Sstevel@tonic-gate v6he.h_addrtype = AF_INET6; 4060Sstevel@tonic-gate v6he.h_addr_list = (char **)v6Addrs; 4070Sstevel@tonic-gate v6he.h_aliases = v6Aliases; 4080Sstevel@tonic-gate he = &v6he; 4090Sstevel@tonic-gate argp->h_errno = v6_h_errno; 4100Sstevel@tonic-gate } 4110Sstevel@tonic-gate 412*2830Sdjl if (he != NULL) { 413*2830Sdjl /* 414*2830Sdjl * if asked to return data in string, 415*2830Sdjl * convert the hostent structure into 416*2830Sdjl * string data 417*2830Sdjl */ 418*2830Sdjl if (argp->buf.result == NULL) { 419*2830Sdjl ret = ent2str(he, a, AF_INET6); 420*2830Sdjl if (ret == NSS_STR_PARSE_SUCCESS) 421*2830Sdjl argp->returnval = argp->buf.buffer; 4220Sstevel@tonic-gate } else { 423*2830Sdjl ret = ent2result(he, a, AF_INET6); 424*2830Sdjl if (ret == NSS_STR_PARSE_SUCCESS) 425*2830Sdjl argp->returnval = argp->buf.result; 426*2830Sdjl } 427*2830Sdjl 428*2830Sdjl if (ret != NSS_STR_PARSE_SUCCESS) { 4290Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 4300Sstevel@tonic-gate if (ret == NSS_STR_PARSE_ERANGE) { 4310Sstevel@tonic-gate argp->erange = 1; 4320Sstevel@tonic-gate } 4330Sstevel@tonic-gate } 4340Sstevel@tonic-gate } 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate if (v6Name != 0) 4370Sstevel@tonic-gate free(v6Name); 4380Sstevel@tonic-gate if (v6Addrs != 0) 4390Sstevel@tonic-gate free(v6Addrs); 4400Sstevel@tonic-gate if (v6Aliases != 0) 4410Sstevel@tonic-gate free(v6Aliases); 4420Sstevel@tonic-gate if (mergeAddrs != 0) 4430Sstevel@tonic-gate free(mergeAddrs); 4440Sstevel@tonic-gate if (mergeAliases != 0) 4450Sstevel@tonic-gate free(mergeAliases); 4460Sstevel@tonic-gate 4470Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry); 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate return (_herrno2nss(argp->h_errno)); 4500Sstevel@tonic-gate } 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate extern nss_status_t __nss_dns_getbyaddr(dns_backend_ptr_t, void *); 4540Sstevel@tonic-gate 4550Sstevel@tonic-gate static nss_status_t 4560Sstevel@tonic-gate getbyaddr(be, a) 4570Sstevel@tonic-gate dns_backend_ptr_t be; 4580Sstevel@tonic-gate void *a; 4590Sstevel@tonic-gate { 4600Sstevel@tonic-gate /* uses the same getbyaddr from IPv4 */ 4610Sstevel@tonic-gate return (__nss_dns_getbyaddr(be, a)); 4620Sstevel@tonic-gate } 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate /*ARGSUSED*/ 4660Sstevel@tonic-gate static nss_status_t 4670Sstevel@tonic-gate _nss_dns_getent(be, args) 4680Sstevel@tonic-gate dns_backend_ptr_t be; 4690Sstevel@tonic-gate void *args; 4700Sstevel@tonic-gate { 4710Sstevel@tonic-gate return (NSS_UNAVAIL); 4720Sstevel@tonic-gate } 4730Sstevel@tonic-gate 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate /*ARGSUSED*/ 4760Sstevel@tonic-gate static nss_status_t 4770Sstevel@tonic-gate _nss_dns_setent(be, dummy) 4780Sstevel@tonic-gate dns_backend_ptr_t be; 4790Sstevel@tonic-gate void *dummy; 4800Sstevel@tonic-gate { 4810Sstevel@tonic-gate /* XXXX not implemented at this point */ 4820Sstevel@tonic-gate return (NSS_UNAVAIL); 4830Sstevel@tonic-gate } 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate /*ARGSUSED*/ 4870Sstevel@tonic-gate static nss_status_t 4880Sstevel@tonic-gate _nss_dns_endent(be, dummy) 4890Sstevel@tonic-gate dns_backend_ptr_t be; 4900Sstevel@tonic-gate void *dummy; 4910Sstevel@tonic-gate { 4920Sstevel@tonic-gate /* XXXX not implemented at this point */ 4930Sstevel@tonic-gate return (NSS_UNAVAIL); 4940Sstevel@tonic-gate } 4950Sstevel@tonic-gate 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate /*ARGSUSED*/ 4980Sstevel@tonic-gate static nss_status_t 4990Sstevel@tonic-gate _nss_dns_destr(be, dummy) 5000Sstevel@tonic-gate dns_backend_ptr_t be; 5010Sstevel@tonic-gate void *dummy; 5020Sstevel@tonic-gate { 5030Sstevel@tonic-gate nss_status_t errp; 5040Sstevel@tonic-gate 5050Sstevel@tonic-gate if (be != 0) { 5060Sstevel@tonic-gate /* === Should change to invoke ops[ENDENT] ? */ 5070Sstevel@tonic-gate sigset_t oldmask, newmask; 5080Sstevel@tonic-gate int mt_disabled = 1; 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) { 5110Sstevel@tonic-gate (void) sigfillset(&newmask); 5120Sstevel@tonic-gate _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); 5130Sstevel@tonic-gate _mutex_lock(&one_lane); 5140Sstevel@tonic-gate } 5150Sstevel@tonic-gate 5160Sstevel@tonic-gate _endhostent(&errp); 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate if (mt_disabled) { 5190Sstevel@tonic-gate _mutex_unlock(&one_lane); 5200Sstevel@tonic-gate _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); 5210Sstevel@tonic-gate } else { 5220Sstevel@tonic-gate (void) (*disable_mt)(); 5230Sstevel@tonic-gate } 5240Sstevel@tonic-gate 5250Sstevel@tonic-gate free(be); 5260Sstevel@tonic-gate } 5270Sstevel@tonic-gate return (NSS_SUCCESS); /* In case anyone is dumb enough to check */ 5280Sstevel@tonic-gate } 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate 5310Sstevel@tonic-gate 5320Sstevel@tonic-gate static dns_backend_op_t ipnodes_ops[] = { 5330Sstevel@tonic-gate _nss_dns_destr, 5340Sstevel@tonic-gate _nss_dns_endent, 5350Sstevel@tonic-gate _nss_dns_setent, 5360Sstevel@tonic-gate _nss_dns_getent, 5370Sstevel@tonic-gate getbyname, 5380Sstevel@tonic-gate getbyaddr, 5390Sstevel@tonic-gate }; 5400Sstevel@tonic-gate 5410Sstevel@tonic-gate /*ARGSUSED*/ 5420Sstevel@tonic-gate nss_backend_t * 5430Sstevel@tonic-gate _nss_dns_ipnodes_constr(dummy1, dummy2, dummy3) 5440Sstevel@tonic-gate const char *dummy1, *dummy2, *dummy3; 5450Sstevel@tonic-gate { 5460Sstevel@tonic-gate return (_nss_dns_constr(ipnodes_ops, 5470Sstevel@tonic-gate sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0]))); 5480Sstevel@tonic-gate } 549*2830Sdjl 550*2830Sdjl /* 551*2830Sdjl * optional NSS2 packed backend gethostsbyipnode with ttl 552*2830Sdjl * entry point. 553*2830Sdjl * 554*2830Sdjl * Returns: 555*2830Sdjl * NSS_SUCCESS - successful 556*2830Sdjl * NSS_NOTFOUND - successful but nothing found 557*2830Sdjl * NSS_ERROR - fallback to NSS backend lookup mode 558*2830Sdjl * If successful, buffer will be filled with valid data 559*2830Sdjl * 560*2830Sdjl */ 561*2830Sdjl 562*2830Sdjl /*ARGSUSED*/ 563*2830Sdjl nss_status_t 564*2830Sdjl _nss_get_dns_ipnodes_name(dns_backend_ptr_t *be, void **bufp, size_t *sizep) 565*2830Sdjl { 566*2830Sdjl return (_nss_dns_gethost_withttl(*bufp, *sizep, 1)); 567*2830Sdjl } 568