]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/net/gethostbynis.c
Import DTS includes from 4.19
[FreeBSD/FreeBSD.git] / lib / libc / net / gethostbynis.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 1994, Garrett Wollman
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <arpa/nameser.h>
36 #include <netdb.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <string.h>
42 #include <stdarg.h>
43 #include <nsswitch.h>
44 #include <resolv.h>             /* XXX */
45 #ifdef YP
46 #include <rpc/rpc.h>
47 #include <rpcsvc/yp_prot.h>
48 #include <rpcsvc/ypclnt.h>
49 #endif
50 #include "netdb_private.h"
51
52 #ifdef YP
53 static int
54 _gethostbynis(const char *name, char *map, int af, struct hostent *he,
55     struct hostent_data *hed)
56 {
57         char *p, *bp, *ep;
58         char *cp, **q;
59         char *result;
60         int resultlen, size, addrok = 0;
61         char ypbuf[YPMAXRECORD + 2];
62         res_state statp;
63
64         statp = __res_state();
65         switch(af) {
66         case AF_INET:
67                 size = NS_INADDRSZ;
68                 break;
69         case AF_INET6:
70                 size = NS_IN6ADDRSZ;
71                 break;
72         default:
73                 errno = EAFNOSUPPORT;
74                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
75                 return (-1);
76         }
77
78         if (hed->yp_domain == (char *)NULL)
79                 if (yp_get_default_domain (&hed->yp_domain)) {
80                         RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
81                         return (-1);
82                 }
83
84         if (yp_match(hed->yp_domain, map, name, strlen(name), &result,
85             &resultlen)) {
86                 RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
87                 return (-1);
88         }
89
90         /* avoid potential memory leak */
91         bcopy((char *)result, (char *)&ypbuf, resultlen);
92         ypbuf[resultlen] = '\0';
93         free(result);
94         result = (char *)&ypbuf;
95
96         if ((cp = strchr(result, '\n')))
97                 *cp = '\0';
98
99         cp = strpbrk(result, " \t");
100         *cp++ = '\0';
101         he->h_addr_list = hed->h_addr_ptrs;
102         he->h_addr = (char *)hed->host_addr;
103         switch (af) {
104         case AF_INET:
105                 addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
106                 if (addrok != 1)
107                         break;
108                 if (statp->options & RES_USE_INET6) {
109                         _map_v4v6_address((char *)hed->host_addr,
110                             (char *)hed->host_addr);
111                         af = AF_INET6;
112                         size = NS_IN6ADDRSZ;
113                 }
114                 break;
115         case AF_INET6:
116                 addrok = inet_pton(af, result, hed->host_addr);
117                 break;
118         }
119         if (addrok != 1) {
120                 RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
121                 return (-1);
122         }
123         he->h_addr_list[1] = NULL;
124         he->h_length = size;
125         he->h_addrtype = af;
126         while (*cp == ' ' || *cp == '\t')
127                 cp++;
128         bp = hed->hostbuf;
129         ep = hed->hostbuf + sizeof hed->hostbuf;
130         he->h_name = bp;
131         q = he->h_aliases = hed->host_aliases;
132         p = strpbrk(cp, " \t");
133         if (p != NULL)
134                 *p++ = '\0';
135         size = strlen(cp) + 1;
136         if (ep - bp < size) {
137                 RES_SET_H_ERRNO(statp, NO_RECOVERY);
138                 return (-1);
139         }
140         strlcpy(bp, cp, ep - bp);
141         bp += size;
142         cp = p;
143         while (cp && *cp) {
144                 if (*cp == ' ' || *cp == '\t') {
145                         cp++;
146                         continue;
147                 }
148                 if (q >= &hed->host_aliases[_MAXALIASES - 1])
149                         break;
150                 p = strpbrk(cp, " \t");
151                 if (p != NULL)
152                         *p++ = '\0';
153                 size = strlen(cp) + 1;
154                 if (ep - bp < size)
155                         break;
156                 strlcpy(bp, cp, ep - bp);
157                 *q++ = bp;
158                 bp += size;
159                 cp = p;
160         }
161         *q = NULL;
162         return (0);
163 }
164
165 static int
166 _gethostbynisname_r(const char *name, int af, struct hostent *he,
167     struct hostent_data *hed)
168 {
169         char *map;
170
171         switch (af) {
172         case AF_INET:
173                 map = "hosts.byname";
174                 break;
175         default:
176                 map = "ipnodes.byname";
177                 break;
178         }
179         return (_gethostbynis(name, map, af, he, hed));
180 }
181
182 static int
183 _gethostbynisaddr_r(const void *addr, socklen_t len, int af,
184     struct hostent *he, struct hostent_data *hed)
185 {
186         char *map;
187         char numaddr[46];
188
189         switch (af) {
190         case AF_INET:
191                 map = "hosts.byaddr";
192                 break;
193         default:
194                 map = "ipnodes.byaddr";
195                 break;
196         }
197         if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
198                 return (-1);
199         return (_gethostbynis(numaddr, map, af, he, hed));
200 }
201 #endif /* YP */
202
203 int
204 _nis_gethostbyname(void *rval, void *cb_data, va_list ap)
205 {
206 #ifdef YP
207         const char *name;
208         int af;
209         char *buffer;
210         size_t buflen;
211         int *errnop, *h_errnop;
212         struct hostent *hptr, he;
213         struct hostent_data *hed;
214         res_state statp;
215
216         name = va_arg(ap, const char *);
217         af = va_arg(ap, int);
218         hptr = va_arg(ap, struct hostent *);
219         buffer = va_arg(ap, char *);
220         buflen = va_arg(ap, size_t);
221         errnop = va_arg(ap, int *);
222         h_errnop = va_arg(ap, int *);
223
224         *((struct hostent **)rval) = NULL;
225
226         statp = __res_state();
227         if ((hed = __hostent_data_init()) == NULL) {
228                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
229                 *h_errnop = statp->res_h_errno;
230                 return (NS_NOTFOUND);
231         }
232
233         if (_gethostbynisname_r(name, af, &he, hed) != 0) {
234                 *h_errnop = statp->res_h_errno;
235                 return (NS_NOTFOUND);
236         }
237         if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
238                 *errnop = errno;
239                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
240                 *h_errnop = statp->res_h_errno;
241                 return (NS_RETURN);
242         }
243         *((struct hostent **)rval) = hptr;
244         return (NS_SUCCESS);
245 #else
246         *((struct hostent **)rval) = NULL;
247         return (NS_UNAVAIL);
248 #endif
249 }
250
251 int
252 _nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
253 {
254 #ifdef YP
255         const void *addr;
256         socklen_t len;
257         int af;
258         char *buffer;
259         size_t buflen;
260         int *errnop, *h_errnop;
261         struct hostent *hptr, he;
262         struct hostent_data *hed;
263         res_state statp;
264
265         addr = va_arg(ap, const void *);
266         len = va_arg(ap, socklen_t);
267         af = va_arg(ap, int);
268         hptr = va_arg(ap, struct hostent *);
269         buffer = va_arg(ap, char *);
270         buflen = va_arg(ap, size_t);
271         errnop = va_arg(ap, int *);
272         h_errnop = va_arg(ap, int *);
273
274         *((struct hostent **)rval) = NULL;
275
276         statp = __res_state();
277         if ((hed = __hostent_data_init()) == NULL) {
278                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
279                 *h_errnop = statp->res_h_errno;
280                 return (NS_NOTFOUND);
281         }
282
283         if (_gethostbynisaddr_r(addr, len, af, &he, hed) != 0) {
284                 *h_errnop = statp->res_h_errno;
285                 return (NS_NOTFOUND);
286         }
287         if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
288                 *errnop = errno;
289                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
290                 *h_errnop = statp->res_h_errno;
291                 return (NS_RETURN);
292         }
293         *((struct hostent **)rval) = hptr;
294         return (NS_SUCCESS);
295 #else
296         *((struct hostent **)rval) = NULL;
297         return (NS_UNAVAIL);
298 #endif
299 }