]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/net/gethostbynis.c
Increase YPMAXRECORD to 16M to be compatible with Linux.
[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;
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         ypbuf = alloca(resultlen + 2);
92         bcopy(result, ypbuf, resultlen);
93         ypbuf[resultlen] = '\0';
94         free(result);
95         result = ypbuf;
96
97         if ((cp = strchr(result, '\n')))
98                 *cp = '\0';
99
100         cp = strpbrk(result, " \t");
101         *cp++ = '\0';
102         he->h_addr_list = hed->h_addr_ptrs;
103         he->h_addr = (char *)hed->host_addr;
104         switch (af) {
105         case AF_INET:
106                 addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
107                 if (addrok != 1)
108                         break;
109                 if (statp->options & RES_USE_INET6) {
110                         _map_v4v6_address((char *)hed->host_addr,
111                             (char *)hed->host_addr);
112                         af = AF_INET6;
113                         size = NS_IN6ADDRSZ;
114                 }
115                 break;
116         case AF_INET6:
117                 addrok = inet_pton(af, result, hed->host_addr);
118                 break;
119         }
120         if (addrok != 1) {
121                 RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
122                 return (-1);
123         }
124         he->h_addr_list[1] = NULL;
125         he->h_length = size;
126         he->h_addrtype = af;
127         while (*cp == ' ' || *cp == '\t')
128                 cp++;
129         bp = hed->hostbuf;
130         ep = hed->hostbuf + sizeof hed->hostbuf;
131         he->h_name = bp;
132         q = he->h_aliases = hed->host_aliases;
133         p = strpbrk(cp, " \t");
134         if (p != NULL)
135                 *p++ = '\0';
136         size = strlen(cp) + 1;
137         if (ep - bp < size) {
138                 RES_SET_H_ERRNO(statp, NO_RECOVERY);
139                 return (-1);
140         }
141         strlcpy(bp, cp, ep - bp);
142         bp += size;
143         cp = p;
144         while (cp && *cp) {
145                 if (*cp == ' ' || *cp == '\t') {
146                         cp++;
147                         continue;
148                 }
149                 if (q >= &hed->host_aliases[_MAXALIASES - 1])
150                         break;
151                 p = strpbrk(cp, " \t");
152                 if (p != NULL)
153                         *p++ = '\0';
154                 size = strlen(cp) + 1;
155                 if (ep - bp < size)
156                         break;
157                 strlcpy(bp, cp, ep - bp);
158                 *q++ = bp;
159                 bp += size;
160                 cp = p;
161         }
162         *q = NULL;
163         return (0);
164 }
165
166 static int
167 _gethostbynisname_r(const char *name, int af, struct hostent *he,
168     struct hostent_data *hed)
169 {
170         char *map;
171
172         switch (af) {
173         case AF_INET:
174                 map = "hosts.byname";
175                 break;
176         default:
177                 map = "ipnodes.byname";
178                 break;
179         }
180         return (_gethostbynis(name, map, af, he, hed));
181 }
182
183 static int
184 _gethostbynisaddr_r(const void *addr, socklen_t len, int af,
185     struct hostent *he, struct hostent_data *hed)
186 {
187         char *map;
188         char numaddr[46];
189
190         switch (af) {
191         case AF_INET:
192                 map = "hosts.byaddr";
193                 break;
194         default:
195                 map = "ipnodes.byaddr";
196                 break;
197         }
198         if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
199                 return (-1);
200         return (_gethostbynis(numaddr, map, af, he, hed));
201 }
202 #endif /* YP */
203
204 int
205 _nis_gethostbyname(void *rval, void *cb_data, va_list ap)
206 {
207 #ifdef YP
208         const char *name;
209         int af;
210         char *buffer;
211         size_t buflen;
212         int *errnop, *h_errnop;
213         struct hostent *hptr, he;
214         struct hostent_data *hed;
215         res_state statp;
216
217         name = va_arg(ap, const char *);
218         af = va_arg(ap, int);
219         hptr = va_arg(ap, struct hostent *);
220         buffer = va_arg(ap, char *);
221         buflen = va_arg(ap, size_t);
222         errnop = va_arg(ap, int *);
223         h_errnop = va_arg(ap, int *);
224
225         *((struct hostent **)rval) = NULL;
226
227         statp = __res_state();
228         if ((hed = __hostent_data_init()) == NULL) {
229                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
230                 *h_errnop = statp->res_h_errno;
231                 return (NS_NOTFOUND);
232         }
233
234         if (_gethostbynisname_r(name, af, &he, hed) != 0) {
235                 *h_errnop = statp->res_h_errno;
236                 return (NS_NOTFOUND);
237         }
238         if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
239                 *errnop = errno;
240                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
241                 *h_errnop = statp->res_h_errno;
242                 return (NS_RETURN);
243         }
244         *((struct hostent **)rval) = hptr;
245         return (NS_SUCCESS);
246 #else
247         *((struct hostent **)rval) = NULL;
248         return (NS_UNAVAIL);
249 #endif
250 }
251
252 int
253 _nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
254 {
255 #ifdef YP
256         const void *addr;
257         socklen_t len;
258         int af;
259         char *buffer;
260         size_t buflen;
261         int *errnop, *h_errnop;
262         struct hostent *hptr, he;
263         struct hostent_data *hed;
264         res_state statp;
265
266         addr = va_arg(ap, const void *);
267         len = va_arg(ap, socklen_t);
268         af = va_arg(ap, int);
269         hptr = va_arg(ap, struct hostent *);
270         buffer = va_arg(ap, char *);
271         buflen = va_arg(ap, size_t);
272         errnop = va_arg(ap, int *);
273         h_errnop = va_arg(ap, int *);
274
275         *((struct hostent **)rval) = NULL;
276
277         statp = __res_state();
278         if ((hed = __hostent_data_init()) == NULL) {
279                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
280                 *h_errnop = statp->res_h_errno;
281                 return (NS_NOTFOUND);
282         }
283
284         if (_gethostbynisaddr_r(addr, len, af, &he, hed) != 0) {
285                 *h_errnop = statp->res_h_errno;
286                 return (NS_NOTFOUND);
287         }
288         if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
289                 *errnop = errno;
290                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
291                 *h_errnop = statp->res_h_errno;
292                 return (NS_RETURN);
293         }
294         *((struct hostent **)rval) = hptr;
295         return (NS_SUCCESS);
296 #else
297         *((struct hostent **)rval) = NULL;
298         return (NS_UNAVAIL);
299 #endif
300 }