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