xref: /freebsd/lib/libc/net/gethostbynis.c (revision 559a218c9b257775fb249b67945fe4a05b7a6b9f)
11363f04cSPaul Traina /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3d915a14eSPedro F. Giffuni  *
41363f04cSPaul Traina  * Copyright (c) 1994, Garrett Wollman
51363f04cSPaul Traina  *
61363f04cSPaul Traina  * Redistribution and use in source and binary forms, with or without
71363f04cSPaul Traina  * modification, are permitted provided that the following conditions
81363f04cSPaul Traina  * are met:
91363f04cSPaul Traina  * 1. Redistributions of source code must retain the above copyright
101363f04cSPaul Traina  *    notice, this list of conditions and the following disclaimer.
111363f04cSPaul Traina  * 2. Redistributions in binary form must reproduce the above copyright
121363f04cSPaul Traina  *    notice, this list of conditions and the following disclaimer in the
131363f04cSPaul Traina  *    documentation and/or other materials provided with the distribution.
141363f04cSPaul Traina  *
151363f04cSPaul Traina  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
161363f04cSPaul Traina  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
171363f04cSPaul Traina  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
181363f04cSPaul Traina  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
191363f04cSPaul Traina  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
201363f04cSPaul Traina  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
211363f04cSPaul Traina  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221363f04cSPaul Traina  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
231363f04cSPaul Traina  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241363f04cSPaul Traina  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251363f04cSPaul Traina  * SUCH DAMAGE.
261363f04cSPaul Traina  */
271363f04cSPaul Traina 
281363f04cSPaul Traina #include <sys/param.h>
291363f04cSPaul Traina #include <sys/socket.h>
301363f04cSPaul Traina #include <netinet/in.h>
311363f04cSPaul Traina #include <arpa/inet.h>
32f0f3d5afSAndrew Gallatin #include <arpa/nameser.h>
331363f04cSPaul Traina #include <netdb.h>
341363f04cSPaul Traina #include <stdio.h>
3551295a4dSJordan K. Hubbard #include <stdlib.h>
361363f04cSPaul Traina #include <ctype.h>
371363f04cSPaul Traina #include <errno.h>
381363f04cSPaul Traina #include <string.h>
39248aee62SJacques Vidrine #include <stdarg.h>
40248aee62SJacques Vidrine #include <nsswitch.h>
41e692b618SHajimu UMEMOTO #include <resolv.h>		/* XXX */
426daf1720SBill Paul #ifdef YP
436daf1720SBill Paul #include <rpc/rpc.h>
446daf1720SBill Paul #include <rpcsvc/yp_prot.h>
456daf1720SBill Paul #include <rpcsvc/ypclnt.h>
466daf1720SBill Paul #endif
47aa2f4ec7SHajimu UMEMOTO #include "netdb_private.h"
481363f04cSPaul Traina 
491363f04cSPaul Traina #ifdef YP
50aa2f4ec7SHajimu UMEMOTO static int
_gethostbynis(const char * name,char * map,int af,struct hostent * he,struct hostent_data * hed)51aa2f4ec7SHajimu UMEMOTO _gethostbynis(const char *name, char *map, int af, struct hostent *he,
52e84892ebSHajimu UMEMOTO     struct hostent_data *hed)
531363f04cSPaul Traina {
54aa2f4ec7SHajimu UMEMOTO 	char *p, *bp, *ep;
558fb3f3f6SDavid E. O'Brien 	char *cp, **q;
561363f04cSPaul Traina 	char *result;
5772572cc6SHajimu UMEMOTO 	int resultlen, size, addrok = 0;
586b462d27SKonstantin Belousov 	char *ypbuf;
59d3ac2b30SHajimu UMEMOTO 	res_state statp;
601363f04cSPaul Traina 
61d3ac2b30SHajimu UMEMOTO 	statp = __res_state();
625ce1c533SPeter Wemm 	switch(af) {
635ce1c533SPeter Wemm 	case AF_INET:
64f0f3d5afSAndrew Gallatin 		size = NS_INADDRSZ;
655ce1c533SPeter Wemm 		break;
665ce1c533SPeter Wemm 	case AF_INET6:
67f0f3d5afSAndrew Gallatin 		size = NS_IN6ADDRSZ;
6872572cc6SHajimu UMEMOTO 		break;
6972572cc6SHajimu UMEMOTO 	default:
705ce1c533SPeter Wemm 		errno = EAFNOSUPPORT;
71d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
72d3ac2b30SHajimu UMEMOTO 		return (-1);
735ce1c533SPeter Wemm 	}
745ce1c533SPeter Wemm 
75aa2f4ec7SHajimu UMEMOTO 	if (hed->yp_domain == (char *)NULL)
76aa2f4ec7SHajimu UMEMOTO 		if (yp_get_default_domain (&hed->yp_domain)) {
77d3ac2b30SHajimu UMEMOTO 			RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
78d3ac2b30SHajimu UMEMOTO 			return (-1);
796737f02eSJacques Vidrine 		}
801363f04cSPaul Traina 
81aa2f4ec7SHajimu UMEMOTO 	if (yp_match(hed->yp_domain, map, name, strlen(name), &result,
82aa2f4ec7SHajimu UMEMOTO 	    &resultlen)) {
83d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
84d3ac2b30SHajimu UMEMOTO 		return (-1);
856737f02eSJacques Vidrine 	}
861363f04cSPaul Traina 
876daf1720SBill Paul 	/* avoid potential memory leak */
886b462d27SKonstantin Belousov 	ypbuf = alloca(resultlen + 2);
896b462d27SKonstantin Belousov 	bcopy(result, ypbuf, resultlen);
90f360d1efSBill Paul 	ypbuf[resultlen] = '\0';
916daf1720SBill Paul 	free(result);
926b462d27SKonstantin Belousov 	result = ypbuf;
936daf1720SBill Paul 
94b3608ae1SEd Schouten 	if ((cp = strchr(result, '\n')))
951363f04cSPaul Traina 		*cp = '\0';
961363f04cSPaul Traina 
971363f04cSPaul Traina 	cp = strpbrk(result, " \t");
981363f04cSPaul Traina 	*cp++ = '\0';
99aa2f4ec7SHajimu UMEMOTO 	he->h_addr_list = hed->h_addr_ptrs;
100aa2f4ec7SHajimu UMEMOTO 	he->h_addr = (char *)hed->host_addr;
10172572cc6SHajimu UMEMOTO 	switch (af) {
10272572cc6SHajimu UMEMOTO 	case AF_INET:
103aa2f4ec7SHajimu UMEMOTO 		addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
104e692b618SHajimu UMEMOTO 		if (addrok != 1)
105e692b618SHajimu UMEMOTO 			break;
106d3ac2b30SHajimu UMEMOTO 		if (statp->options & RES_USE_INET6) {
107e692b618SHajimu UMEMOTO 			_map_v4v6_address((char *)hed->host_addr,
108e692b618SHajimu UMEMOTO 			    (char *)hed->host_addr);
109e692b618SHajimu UMEMOTO 			af = AF_INET6;
110e692b618SHajimu UMEMOTO 			size = NS_IN6ADDRSZ;
111e692b618SHajimu UMEMOTO 		}
11272572cc6SHajimu UMEMOTO 		break;
11372572cc6SHajimu UMEMOTO 	case AF_INET6:
114aa2f4ec7SHajimu UMEMOTO 		addrok = inet_pton(af, result, hed->host_addr);
11572572cc6SHajimu UMEMOTO 		break;
11672572cc6SHajimu UMEMOTO 	}
11772572cc6SHajimu UMEMOTO 	if (addrok != 1) {
118d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
119d3ac2b30SHajimu UMEMOTO 		return (-1);
12072572cc6SHajimu UMEMOTO 	}
121aa2f4ec7SHajimu UMEMOTO 	he->h_addr_list[1] = NULL;
122aa2f4ec7SHajimu UMEMOTO 	he->h_length = size;
123aa2f4ec7SHajimu UMEMOTO 	he->h_addrtype = af;
1241363f04cSPaul Traina 	while (*cp == ' ' || *cp == '\t')
1251363f04cSPaul Traina 		cp++;
126aa2f4ec7SHajimu UMEMOTO 	bp = hed->hostbuf;
127aa2f4ec7SHajimu UMEMOTO 	ep = hed->hostbuf + sizeof hed->hostbuf;
128aa2f4ec7SHajimu UMEMOTO 	he->h_name = bp;
129aa2f4ec7SHajimu UMEMOTO 	q = he->h_aliases = hed->host_aliases;
130aa2f4ec7SHajimu UMEMOTO 	p = strpbrk(cp, " \t");
131aa2f4ec7SHajimu UMEMOTO 	if (p != NULL)
132aa2f4ec7SHajimu UMEMOTO 		*p++ = '\0';
133aa2f4ec7SHajimu UMEMOTO 	size = strlen(cp) + 1;
134aa2f4ec7SHajimu UMEMOTO 	if (ep - bp < size) {
135d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NO_RECOVERY);
136d3ac2b30SHajimu UMEMOTO 		return (-1);
137aa2f4ec7SHajimu UMEMOTO 	}
138aa2f4ec7SHajimu UMEMOTO 	strlcpy(bp, cp, ep - bp);
139aa2f4ec7SHajimu UMEMOTO 	bp += size;
140aa2f4ec7SHajimu UMEMOTO 	cp = p;
1411363f04cSPaul Traina 	while (cp && *cp) {
1421363f04cSPaul Traina 		if (*cp == ' ' || *cp == '\t') {
1431363f04cSPaul Traina 			cp++;
1441363f04cSPaul Traina 			continue;
1451363f04cSPaul Traina 		}
146aa2f4ec7SHajimu UMEMOTO 		if (q >= &hed->host_aliases[_MAXALIASES - 1])
147aa2f4ec7SHajimu UMEMOTO 			break;
148aa2f4ec7SHajimu UMEMOTO 		p = strpbrk(cp, " \t");
149aa2f4ec7SHajimu UMEMOTO 		if (p != NULL)
150aa2f4ec7SHajimu UMEMOTO 			*p++ = '\0';
151aa2f4ec7SHajimu UMEMOTO 		size = strlen(cp) + 1;
152aa2f4ec7SHajimu UMEMOTO 		if (ep - bp < size)
153aa2f4ec7SHajimu UMEMOTO 			break;
154aa2f4ec7SHajimu UMEMOTO 		strlcpy(bp, cp, ep - bp);
155aa2f4ec7SHajimu UMEMOTO 		*q++ = bp;
156aa2f4ec7SHajimu UMEMOTO 		bp += size;
157aa2f4ec7SHajimu UMEMOTO 		cp = p;
1581363f04cSPaul Traina 	}
1591363f04cSPaul Traina 	*q = NULL;
160d3ac2b30SHajimu UMEMOTO 	return (0);
161248aee62SJacques Vidrine }
16272572cc6SHajimu UMEMOTO 
163aa2f4ec7SHajimu UMEMOTO static int
_gethostbynisname_r(const char * name,int af,struct hostent * he,struct hostent_data * hed)164aa2f4ec7SHajimu UMEMOTO _gethostbynisname_r(const char *name, int af, struct hostent *he,
165aa2f4ec7SHajimu UMEMOTO     struct hostent_data *hed)
16672572cc6SHajimu UMEMOTO {
16772572cc6SHajimu UMEMOTO 	char *map;
16872572cc6SHajimu UMEMOTO 
16972572cc6SHajimu UMEMOTO 	switch (af) {
17072572cc6SHajimu UMEMOTO 	case AF_INET:
17172572cc6SHajimu UMEMOTO 		map = "hosts.byname";
17272572cc6SHajimu UMEMOTO 		break;
17372572cc6SHajimu UMEMOTO 	default:
17472572cc6SHajimu UMEMOTO 		map = "ipnodes.byname";
17572572cc6SHajimu UMEMOTO 		break;
17672572cc6SHajimu UMEMOTO 	}
177d3ac2b30SHajimu UMEMOTO 	return (_gethostbynis(name, map, af, he, hed));
17872572cc6SHajimu UMEMOTO }
17972572cc6SHajimu UMEMOTO 
180aa2f4ec7SHajimu UMEMOTO static int
_gethostbynisaddr_r(const void * addr,socklen_t len,int af,struct hostent * he,struct hostent_data * hed)1813da59cd0SHajimu UMEMOTO _gethostbynisaddr_r(const void *addr, socklen_t len, int af,
1823da59cd0SHajimu UMEMOTO     struct hostent *he, struct hostent_data *hed)
18372572cc6SHajimu UMEMOTO {
18472572cc6SHajimu UMEMOTO 	char *map;
1850d389e72SHajimu UMEMOTO 	char numaddr[46];
18672572cc6SHajimu UMEMOTO 
18772572cc6SHajimu UMEMOTO 	switch (af) {
18872572cc6SHajimu UMEMOTO 	case AF_INET:
18972572cc6SHajimu UMEMOTO 		map = "hosts.byaddr";
19072572cc6SHajimu UMEMOTO 		break;
19172572cc6SHajimu UMEMOTO 	default:
19272572cc6SHajimu UMEMOTO 		map = "ipnodes.byaddr";
19372572cc6SHajimu UMEMOTO 		break;
19472572cc6SHajimu UMEMOTO 	}
1950d389e72SHajimu UMEMOTO 	if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
196d3ac2b30SHajimu UMEMOTO 		return (-1);
197d3ac2b30SHajimu UMEMOTO 	return (_gethostbynis(numaddr, map, af, he, hed));
19872572cc6SHajimu UMEMOTO }
1991363f04cSPaul Traina #endif /* YP */
200248aee62SJacques Vidrine 
201248aee62SJacques Vidrine int
_nis_gethostbyname(void * rval,void * cb_data,va_list ap)202248aee62SJacques Vidrine _nis_gethostbyname(void *rval, void *cb_data, va_list ap)
203248aee62SJacques Vidrine {
204248aee62SJacques Vidrine #ifdef YP
2055ce1c533SPeter Wemm 	const char *name;
2065ce1c533SPeter Wemm 	int af;
207d3ac2b30SHajimu UMEMOTO 	char *buffer;
208d3ac2b30SHajimu UMEMOTO 	size_t buflen;
209d3ac2b30SHajimu UMEMOTO 	int *errnop, *h_errnop;
210d3ac2b30SHajimu UMEMOTO 	struct hostent *hptr, he;
211aa2f4ec7SHajimu UMEMOTO 	struct hostent_data *hed;
212d3ac2b30SHajimu UMEMOTO 	res_state statp;
213248aee62SJacques Vidrine 
214248aee62SJacques Vidrine 	name = va_arg(ap, const char *);
215248aee62SJacques Vidrine 	af = va_arg(ap, int);
216d3ac2b30SHajimu UMEMOTO 	hptr = va_arg(ap, struct hostent *);
217d3ac2b30SHajimu UMEMOTO 	buffer = va_arg(ap, char *);
218d3ac2b30SHajimu UMEMOTO 	buflen = va_arg(ap, size_t);
219d3ac2b30SHajimu UMEMOTO 	errnop = va_arg(ap, int *);
220d3ac2b30SHajimu UMEMOTO 	h_errnop = va_arg(ap, int *);
221248aee62SJacques Vidrine 
222d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = NULL;
223d3ac2b30SHajimu UMEMOTO 
224d3ac2b30SHajimu UMEMOTO 	statp = __res_state();
225d3ac2b30SHajimu UMEMOTO 	if ((hed = __hostent_data_init()) == NULL) {
226d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
227d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
228d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
229d3ac2b30SHajimu UMEMOTO 	}
230d3ac2b30SHajimu UMEMOTO 
231d3ac2b30SHajimu UMEMOTO 	if (_gethostbynisname_r(name, af, &he, hed) != 0) {
232d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
233d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
234d3ac2b30SHajimu UMEMOTO 	}
235d3ac2b30SHajimu UMEMOTO 	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
236225edeacSHajimu UMEMOTO 		*errnop = errno;
237225edeacSHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
238d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
239225edeacSHajimu UMEMOTO 		return (NS_RETURN);
240d3ac2b30SHajimu UMEMOTO 	}
241d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = hptr;
242d3ac2b30SHajimu UMEMOTO 	return (NS_SUCCESS);
243248aee62SJacques Vidrine #else
244d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = NULL;
245d3ac2b30SHajimu UMEMOTO 	return (NS_UNAVAIL);
246248aee62SJacques Vidrine #endif
2471363f04cSPaul Traina }
2481363f04cSPaul Traina 
249248aee62SJacques Vidrine int
_nis_gethostbyaddr(void * rval,void * cb_data,va_list ap)250248aee62SJacques Vidrine _nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
251248aee62SJacques Vidrine {
252248aee62SJacques Vidrine #ifdef YP
2533da59cd0SHajimu UMEMOTO 	const void *addr;
2543da59cd0SHajimu UMEMOTO 	socklen_t len;
2555ce1c533SPeter Wemm 	int af;
256d3ac2b30SHajimu UMEMOTO 	char *buffer;
257d3ac2b30SHajimu UMEMOTO 	size_t buflen;
258d3ac2b30SHajimu UMEMOTO 	int *errnop, *h_errnop;
259d3ac2b30SHajimu UMEMOTO 	struct hostent *hptr, he;
260aa2f4ec7SHajimu UMEMOTO 	struct hostent_data *hed;
261d3ac2b30SHajimu UMEMOTO 	res_state statp;
262248aee62SJacques Vidrine 
2633da59cd0SHajimu UMEMOTO 	addr = va_arg(ap, const void *);
2643da59cd0SHajimu UMEMOTO 	len = va_arg(ap, socklen_t);
265248aee62SJacques Vidrine 	af = va_arg(ap, int);
266d3ac2b30SHajimu UMEMOTO 	hptr = va_arg(ap, struct hostent *);
267d3ac2b30SHajimu UMEMOTO 	buffer = va_arg(ap, char *);
268d3ac2b30SHajimu UMEMOTO 	buflen = va_arg(ap, size_t);
269d3ac2b30SHajimu UMEMOTO 	errnop = va_arg(ap, int *);
270d3ac2b30SHajimu UMEMOTO 	h_errnop = va_arg(ap, int *);
271248aee62SJacques Vidrine 
272d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = NULL;
273d3ac2b30SHajimu UMEMOTO 
274d3ac2b30SHajimu UMEMOTO 	statp = __res_state();
275d3ac2b30SHajimu UMEMOTO 	if ((hed = __hostent_data_init()) == NULL) {
276d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
277d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
278d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
279d3ac2b30SHajimu UMEMOTO 	}
280d3ac2b30SHajimu UMEMOTO 
281d3ac2b30SHajimu UMEMOTO 	if (_gethostbynisaddr_r(addr, len, af, &he, hed) != 0) {
282d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
283d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
284d3ac2b30SHajimu UMEMOTO 	}
285d3ac2b30SHajimu UMEMOTO 	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
286225edeacSHajimu UMEMOTO 		*errnop = errno;
287225edeacSHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
288d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
289225edeacSHajimu UMEMOTO 		return (NS_RETURN);
290d3ac2b30SHajimu UMEMOTO 	}
291d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = hptr;
292d3ac2b30SHajimu UMEMOTO 	return (NS_SUCCESS);
293248aee62SJacques Vidrine #else
294d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = NULL;
295d3ac2b30SHajimu UMEMOTO 	return (NS_UNAVAIL);
296248aee62SJacques Vidrine #endif
2971363f04cSPaul Traina }
298