1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright (c) 1993, 1998-2000 by Sun Microsystems, Inc. 24*0Sstevel@tonic-gate * All rights reserved. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * gethostent.c 31*0Sstevel@tonic-gate * 32*0Sstevel@tonic-gate * In order to avoid duplicating libresolv code here, and since libresolv.so.2 33*0Sstevel@tonic-gate * provides res_-equivalents of the getXbyY and {set,get}Xent, lets call 34*0Sstevel@tonic-gate * re_gethostbyaddr() and so on from this file. Among other things, this 35*0Sstevel@tonic-gate * should help us avoid problems like the one described in bug 1264386, 36*0Sstevel@tonic-gate * where the internal getanswer() acquired new functionality in BIND 4.9.3, 37*0Sstevel@tonic-gate * but the local copy of getanswer() in this file wasn't updated, so that new 38*0Sstevel@tonic-gate * functionality wasn't available to the name service switch. 39*0Sstevel@tonic-gate */ 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #define gethostbyaddr res_gethostbyaddr 42*0Sstevel@tonic-gate #define gethostbyname res_gethostbyname 43*0Sstevel@tonic-gate #define gethostbyname2 res_gethostbyname2 44*0Sstevel@tonic-gate #define sethostent res_sethostent 45*0Sstevel@tonic-gate #define endhostent res_endhostent 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate #include "dns_common.h" 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate extern char *inet_ntoa(struct in_addr in); 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate struct hostent *_gethostbyname(int *h_errnop, const char *name); 52*0Sstevel@tonic-gate static struct hostent *_gethostbyaddr(int *h_errnop, const char *addr, 53*0Sstevel@tonic-gate int len, int type); 54*0Sstevel@tonic-gate struct hostent *_nss_dns_gethostbyname2(int *h_errnop, const char *name); 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate #pragma weak res_gethostbyname 57*0Sstevel@tonic-gate #pragma weak res_gethostbyname2 58*0Sstevel@tonic-gate #pragma weak res_gethostbyaddr 59*0Sstevel@tonic-gate #pragma weak res_sethostent 60*0Sstevel@tonic-gate #pragma weak res_endhostent 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate nss_backend_t *_nss_dns_constr(dns_backend_op_t ops[], int n_ops); 63*0Sstevel@tonic-gate nss_status_t __nss_dns_getbyaddr(dns_backend_ptr_t, void *); 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate typedef union { 66*0Sstevel@tonic-gate long al; 67*0Sstevel@tonic-gate char ac; 68*0Sstevel@tonic-gate } align; 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate /* 71*0Sstevel@tonic-gate * Internet Name Domain Server (DNS) only implementation. 72*0Sstevel@tonic-gate */ 73*0Sstevel@tonic-gate static struct hostent * 74*0Sstevel@tonic-gate _gethostbyaddr(int *h_errnop, const char *addr, int len, int type) 75*0Sstevel@tonic-gate { 76*0Sstevel@tonic-gate struct hostent *hp; 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate hp = gethostbyaddr(addr, len, type); 79*0Sstevel@tonic-gate *h_errnop = *get_h_errno(); 80*0Sstevel@tonic-gate return (hp); 81*0Sstevel@tonic-gate } 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate struct hostent * 84*0Sstevel@tonic-gate _nss_dns_gethostbyname2(int *h_errnop, const char *name) 85*0Sstevel@tonic-gate { 86*0Sstevel@tonic-gate struct hostent *hp; 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate hp = gethostbyname2(name, AF_INET6); 89*0Sstevel@tonic-gate *h_errnop = *get_h_errno(); 90*0Sstevel@tonic-gate return (hp); 91*0Sstevel@tonic-gate } 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate struct hostent * 94*0Sstevel@tonic-gate _gethostbyname(int *h_errnop, const char *name) 95*0Sstevel@tonic-gate { 96*0Sstevel@tonic-gate struct hostent *hp; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate hp = gethostbyname(name); 99*0Sstevel@tonic-gate *h_errnop = *get_h_errno(); 100*0Sstevel@tonic-gate return (hp); 101*0Sstevel@tonic-gate } 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate static void 104*0Sstevel@tonic-gate _sethostent(errp, stayopen) 105*0Sstevel@tonic-gate nss_status_t *errp; 106*0Sstevel@tonic-gate int stayopen; 107*0Sstevel@tonic-gate { 108*0Sstevel@tonic-gate int ret; 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate ret = sethostent(stayopen); 111*0Sstevel@tonic-gate if (ret == 0) 112*0Sstevel@tonic-gate *errp = NSS_SUCCESS; 113*0Sstevel@tonic-gate else 114*0Sstevel@tonic-gate *errp = NSS_UNAVAIL; 115*0Sstevel@tonic-gate } 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate static void 118*0Sstevel@tonic-gate _endhostent(errp) 119*0Sstevel@tonic-gate nss_status_t *errp; 120*0Sstevel@tonic-gate { 121*0Sstevel@tonic-gate int ret; 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate ret = endhostent(); 124*0Sstevel@tonic-gate if (ret == 0) 125*0Sstevel@tonic-gate *errp = NSS_SUCCESS; 126*0Sstevel@tonic-gate else 127*0Sstevel@tonic-gate *errp = NSS_UNAVAIL; 128*0Sstevel@tonic-gate } 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate /*ARGSUSED*/ 132*0Sstevel@tonic-gate static nss_status_t 133*0Sstevel@tonic-gate getbyname(be, a) 134*0Sstevel@tonic-gate dns_backend_ptr_t be; 135*0Sstevel@tonic-gate void *a; 136*0Sstevel@tonic-gate { 137*0Sstevel@tonic-gate struct hostent *he; 138*0Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 139*0Sstevel@tonic-gate int ret, mt_disabled; 140*0Sstevel@tonic-gate int old_retry; 141*0Sstevel@tonic-gate sigset_t oldmask; 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate switch_resolver_setup(&mt_disabled, &oldmask, &old_retry); 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate he = _gethostbyname(&argp->h_errno, argp->key.name); 146*0Sstevel@tonic-gate if (he != NULL) { 147*0Sstevel@tonic-gate ret = ent2result(he, a, AF_INET); 148*0Sstevel@tonic-gate if (ret == NSS_STR_PARSE_SUCCESS) { 149*0Sstevel@tonic-gate argp->returnval = argp->buf.result; 150*0Sstevel@tonic-gate } else { 151*0Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 152*0Sstevel@tonic-gate if (ret == NSS_STR_PARSE_ERANGE) { 153*0Sstevel@tonic-gate argp->erange = 1; 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate } 156*0Sstevel@tonic-gate } 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry); 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate return (_herrno2nss(argp->h_errno)); 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate /*ARGSUSED*/ 166*0Sstevel@tonic-gate static nss_status_t 167*0Sstevel@tonic-gate getbyaddr(be, a) 168*0Sstevel@tonic-gate dns_backend_ptr_t be; 169*0Sstevel@tonic-gate void *a; 170*0Sstevel@tonic-gate { 171*0Sstevel@tonic-gate return (__nss_dns_getbyaddr(be, a)); 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate /* 176*0Sstevel@tonic-gate * Exposing a DNS backend specific interface so that it doesn't conflict 177*0Sstevel@tonic-gate * with other getbyaddr() routines from other switch backends. 178*0Sstevel@tonic-gate */ 179*0Sstevel@tonic-gate nss_status_t 180*0Sstevel@tonic-gate __nss_dns_getbyaddr(be, a) 181*0Sstevel@tonic-gate dns_backend_ptr_t be; 182*0Sstevel@tonic-gate void *a; 183*0Sstevel@tonic-gate { 184*0Sstevel@tonic-gate size_t n; 185*0Sstevel@tonic-gate struct hostent *he, *he2; 186*0Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 187*0Sstevel@tonic-gate int ret, save_h_errno, mt_disabled; 188*0Sstevel@tonic-gate char **ans, hbuf[MAXHOSTNAMELEN]; 189*0Sstevel@tonic-gate char dst[INET6_ADDRSTRLEN]; 190*0Sstevel@tonic-gate struct in_addr unmapv4; 191*0Sstevel@tonic-gate sigset_t oldmask; 192*0Sstevel@tonic-gate int af, addrlen; 193*0Sstevel@tonic-gate void *addrp; 194*0Sstevel@tonic-gate int old_retry; 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate switch_resolver_setup(&mt_disabled, &oldmask, &old_retry); 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)argp->key.hostaddr.addr)) { 199*0Sstevel@tonic-gate addrp = &unmapv4; 200*0Sstevel@tonic-gate addrlen = sizeof (unmapv4); 201*0Sstevel@tonic-gate af = AF_INET; 202*0Sstevel@tonic-gate memcpy(addrp, &argp->key.hostaddr.addr[12], addrlen); 203*0Sstevel@tonic-gate } else { 204*0Sstevel@tonic-gate addrp = (void *)argp->key.hostaddr.addr; 205*0Sstevel@tonic-gate addrlen = argp->key.hostaddr.len; 206*0Sstevel@tonic-gate af = argp->key.hostaddr.type; 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate he = _gethostbyaddr(&argp->h_errno, addrp, addrlen, af); 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate if (he != NULL) { 211*0Sstevel@tonic-gate if (strlen(he->h_name) >= MAXHOSTNAMELEN) 212*0Sstevel@tonic-gate ret = NSS_STR_PARSE_ERANGE; 213*0Sstevel@tonic-gate else { 214*0Sstevel@tonic-gate /* save a copy of the (alleged) hostname */ 215*0Sstevel@tonic-gate (void) strcpy(hbuf, he->h_name); 216*0Sstevel@tonic-gate n = strlen(hbuf); 217*0Sstevel@tonic-gate if (n < MAXHOSTNAMELEN-1 && hbuf[n-1] != '.') { 218*0Sstevel@tonic-gate (void) strcat(hbuf, "."); 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate ret = ent2result(he, a, argp->key.hostaddr.type); 221*0Sstevel@tonic-gate save_h_errno = argp->h_errno; 222*0Sstevel@tonic-gate } 223*0Sstevel@tonic-gate if (ret == NSS_STR_PARSE_SUCCESS) { 224*0Sstevel@tonic-gate /* 225*0Sstevel@tonic-gate * check to make sure by doing a forward query 226*0Sstevel@tonic-gate * We use _gethostbyname() to avoid the stack, and 227*0Sstevel@tonic-gate * then we throw the result from argp->h_errno away, 228*0Sstevel@tonic-gate * becase we don't care. And besides you want the 229*0Sstevel@tonic-gate * return code from _gethostbyaddr() anyway. 230*0Sstevel@tonic-gate */ 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate if (af == AF_INET) 233*0Sstevel@tonic-gate he2 = _gethostbyname(&argp->h_errno, hbuf); 234*0Sstevel@tonic-gate else 235*0Sstevel@tonic-gate he2 = _nss_dns_gethostbyname2(&argp->h_errno, 236*0Sstevel@tonic-gate hbuf); 237*0Sstevel@tonic-gate if (he2 != (struct hostent *)NULL) { 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate /* until we prove name and addr match */ 240*0Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 241*0Sstevel@tonic-gate for (ans = he2->h_addr_list; *ans; ans++) 242*0Sstevel@tonic-gate if (memcmp(*ans, addrp, addrlen) == 243*0Sstevel@tonic-gate 0) { 244*0Sstevel@tonic-gate argp->h_errno = save_h_errno; 245*0Sstevel@tonic-gate argp->returnval = argp->buf.result; 246*0Sstevel@tonic-gate break; 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate } else { 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate /* 251*0Sstevel@tonic-gate * What to do if _gethostbyname() fails ??? 252*0Sstevel@tonic-gate * We assume they are doing something stupid 253*0Sstevel@tonic-gate * like registering addresses but not names 254*0Sstevel@tonic-gate * (some people actually think that provides 255*0Sstevel@tonic-gate * some "security", through obscurity). So for 256*0Sstevel@tonic-gate * these poor lost souls, because we can't 257*0Sstevel@tonic-gate * PROVE spoofing and because we did try (and 258*0Sstevel@tonic-gate * we don't want a bug filed on this), we let 259*0Sstevel@tonic-gate * this go. And return the name from byaddr. 260*0Sstevel@tonic-gate */ 261*0Sstevel@tonic-gate argp->h_errno = save_h_errno; 262*0Sstevel@tonic-gate argp->returnval = argp->buf.result; 263*0Sstevel@tonic-gate } 264*0Sstevel@tonic-gate /* we've been spoofed, make sure to log it. */ 265*0Sstevel@tonic-gate if (argp->h_errno == HOST_NOT_FOUND) { 266*0Sstevel@tonic-gate if (argp->key.hostaddr.type == AF_INET) 267*0Sstevel@tonic-gate syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", 268*0Sstevel@tonic-gate hbuf, inet_ntoa(*(struct in_addr *)argp->key.hostaddr.addr)); 269*0Sstevel@tonic-gate else 270*0Sstevel@tonic-gate syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", 271*0Sstevel@tonic-gate hbuf, inet_ntop(AF_INET6, (void *) argp->key.hostaddr.addr, 272*0Sstevel@tonic-gate dst, sizeof (dst))); 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate } else { 275*0Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 276*0Sstevel@tonic-gate if (ret == NSS_STR_PARSE_ERANGE) { 277*0Sstevel@tonic-gate argp->erange = 1; 278*0Sstevel@tonic-gate } 279*0Sstevel@tonic-gate } 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate switch_resolver_reset(mt_disabled, oldmask, old_retry); 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate return (_herrno2nss(argp->h_errno)); 285*0Sstevel@tonic-gate } 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate /*ARGSUSED*/ 289*0Sstevel@tonic-gate static nss_status_t 290*0Sstevel@tonic-gate _nss_dns_getent(be, args) 291*0Sstevel@tonic-gate dns_backend_ptr_t be; 292*0Sstevel@tonic-gate void *args; 293*0Sstevel@tonic-gate { 294*0Sstevel@tonic-gate return (NSS_UNAVAIL); 295*0Sstevel@tonic-gate } 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate /*ARGSUSED*/ 299*0Sstevel@tonic-gate static nss_status_t 300*0Sstevel@tonic-gate _nss_dns_setent(be, dummy) 301*0Sstevel@tonic-gate dns_backend_ptr_t be; 302*0Sstevel@tonic-gate void *dummy; 303*0Sstevel@tonic-gate { 304*0Sstevel@tonic-gate nss_status_t errp; 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate sigset_t oldmask, newmask; 307*0Sstevel@tonic-gate int mt_disabled = 1; 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate /* 310*0Sstevel@tonic-gate * Try to enable MT; if not, we have to single-thread libresolv 311*0Sstevel@tonic-gate * access 312*0Sstevel@tonic-gate */ 313*0Sstevel@tonic-gate if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) { 314*0Sstevel@tonic-gate (void) sigfillset(&newmask); 315*0Sstevel@tonic-gate _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); 316*0Sstevel@tonic-gate _mutex_lock(&one_lane); 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate _sethostent(&errp, 1); 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate if (mt_disabled) { 322*0Sstevel@tonic-gate _mutex_unlock(&one_lane); 323*0Sstevel@tonic-gate _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); 324*0Sstevel@tonic-gate } else { 325*0Sstevel@tonic-gate (void) (*disable_mt)(); 326*0Sstevel@tonic-gate } 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate return (errp); 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate /*ARGSUSED*/ 333*0Sstevel@tonic-gate static nss_status_t 334*0Sstevel@tonic-gate _nss_dns_endent(be, dummy) 335*0Sstevel@tonic-gate dns_backend_ptr_t be; 336*0Sstevel@tonic-gate void *dummy; 337*0Sstevel@tonic-gate { 338*0Sstevel@tonic-gate nss_status_t errp; 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate sigset_t oldmask, newmask; 341*0Sstevel@tonic-gate int mt_disabled = 1; 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate /* 344*0Sstevel@tonic-gate * Try to enable MT; if not, we have to single-thread libresolv 345*0Sstevel@tonic-gate * access 346*0Sstevel@tonic-gate */ 347*0Sstevel@tonic-gate if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) { 348*0Sstevel@tonic-gate (void) sigfillset(&newmask); 349*0Sstevel@tonic-gate _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); 350*0Sstevel@tonic-gate _mutex_lock(&one_lane); 351*0Sstevel@tonic-gate } 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate _endhostent(&errp); 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate if (mt_disabled) { 356*0Sstevel@tonic-gate _mutex_unlock(&one_lane); 357*0Sstevel@tonic-gate _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); 358*0Sstevel@tonic-gate } else { 359*0Sstevel@tonic-gate (void) (*disable_mt)(); 360*0Sstevel@tonic-gate } 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate return (errp); 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate /*ARGSUSED*/ 367*0Sstevel@tonic-gate static nss_status_t 368*0Sstevel@tonic-gate _nss_dns_destr(be, dummy) 369*0Sstevel@tonic-gate dns_backend_ptr_t be; 370*0Sstevel@tonic-gate void *dummy; 371*0Sstevel@tonic-gate { 372*0Sstevel@tonic-gate nss_status_t errp; 373*0Sstevel@tonic-gate 374*0Sstevel@tonic-gate if (be != 0) { 375*0Sstevel@tonic-gate /* === Should change to invoke ops[ENDENT] ? */ 376*0Sstevel@tonic-gate sigset_t oldmask, newmask; 377*0Sstevel@tonic-gate int mt_disabled = 1; 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) { 380*0Sstevel@tonic-gate (void) sigfillset(&newmask); 381*0Sstevel@tonic-gate _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); 382*0Sstevel@tonic-gate _mutex_lock(&one_lane); 383*0Sstevel@tonic-gate } 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gate _endhostent(&errp); 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate if (mt_disabled) { 388*0Sstevel@tonic-gate _mutex_unlock(&one_lane); 389*0Sstevel@tonic-gate _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); 390*0Sstevel@tonic-gate } else { 391*0Sstevel@tonic-gate (void) (*disable_mt)(); 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate free(be); 395*0Sstevel@tonic-gate } 396*0Sstevel@tonic-gate return (NSS_SUCCESS); /* In case anyone is dumb enough to check */ 397*0Sstevel@tonic-gate } 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate static dns_backend_op_t host_ops[] = { 401*0Sstevel@tonic-gate _nss_dns_destr, 402*0Sstevel@tonic-gate _nss_dns_endent, 403*0Sstevel@tonic-gate _nss_dns_setent, 404*0Sstevel@tonic-gate _nss_dns_getent, 405*0Sstevel@tonic-gate getbyname, 406*0Sstevel@tonic-gate getbyaddr, 407*0Sstevel@tonic-gate }; 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate /*ARGSUSED*/ 410*0Sstevel@tonic-gate nss_backend_t * 411*0Sstevel@tonic-gate _nss_dns_hosts_constr(dummy1, dummy2, dummy3) 412*0Sstevel@tonic-gate const char *dummy1, *dummy2, *dummy3; 413*0Sstevel@tonic-gate { 414*0Sstevel@tonic-gate return (_nss_dns_constr(host_ops, 415*0Sstevel@tonic-gate sizeof (host_ops) / sizeof (host_ops[0]))); 416*0Sstevel@tonic-gate } 417