13070Spst/*- 23070Spst * Copyright (c) 1994, Garrett Wollman 33070Spst * 43070Spst * Redistribution and use in source and binary forms, with or without 53070Spst * modification, are permitted provided that the following conditions 63070Spst * are met: 73070Spst * 1. Redistributions of source code must retain the above copyright 83070Spst * notice, this list of conditions and the following disclaimer. 93070Spst * 2. Redistributions in binary form must reproduce the above copyright 103070Spst * notice, this list of conditions and the following disclaimer in the 113070Spst * documentation and/or other materials provided with the distribution. 123070Spst * 133070Spst * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND 143070Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 153070Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 163070Spst * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 173070Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 183070Spst * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 193070Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 203070Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 213070Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 223070Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 233070Spst * SUCH DAMAGE. 243070Spst */ 253070Spst 2692986Sobrien#include <sys/cdefs.h> 2792986Sobrien__FBSDID("$FreeBSD$"); 283070Spst 293070Spst#include <sys/param.h> 303070Spst#include <sys/socket.h> 313070Spst#include <netinet/in.h> 323070Spst#include <arpa/inet.h> 3343171Sgallatin#include <arpa/nameser.h> 343070Spst#include <netdb.h> 353070Spst#include <stdio.h> 3617141Sjkh#include <stdlib.h> 373070Spst#include <ctype.h> 383070Spst#include <errno.h> 393070Spst#include <string.h> 4065532Snectar#include <stdarg.h> 4165532Snectar#include <nsswitch.h> 42145721Sume#include <resolv.h> /* XXX */ 4314639Swpaul#ifdef YP 4414639Swpaul#include <rpc/rpc.h> 4514639Swpaul#include <rpcsvc/yp_prot.h> 4614639Swpaul#include <rpcsvc/ypclnt.h> 4714639Swpaul#endif 48145633Sume#include "netdb_private.h" 493070Spst 503070Spst#ifdef YP 51145633Sumestatic int 52145633Sume_gethostbynis(const char *name, char *map, int af, struct hostent *he, 53145728Sume struct hostent_data *hed) 543070Spst{ 55145633Sume char *p, *bp, *ep; 5692889Sobrien char *cp, **q; 573070Spst char *result; 58145550Sume int resultlen, size, addrok = 0; 59145633Sume char ypbuf[YPMAXRECORD + 2]; 60157779Sume res_state statp; 613070Spst 62157779Sume statp = __res_state(); 6317903Speter switch(af) { 6417903Speter case AF_INET: 6543171Sgallatin size = NS_INADDRSZ; 6617903Speter break; 6717903Speter case AF_INET6: 6843171Sgallatin size = NS_IN6ADDRSZ; 69145550Sume break; 70145550Sume default: 7117903Speter errno = EAFNOSUPPORT; 72157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 73157779Sume return (-1); 7417903Speter } 7517903Speter 76145633Sume if (hed->yp_domain == (char *)NULL) 77145633Sume if (yp_get_default_domain (&hed->yp_domain)) { 78157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 79157779Sume return (-1); 8065702Snectar } 813070Spst 82145633Sume if (yp_match(hed->yp_domain, map, name, strlen(name), &result, 83145633Sume &resultlen)) { 84157779Sume RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); 85157779Sume return (-1); 8665702Snectar } 873070Spst 8814639Swpaul /* avoid potential memory leak */ 8914639Swpaul bcopy((char *)result, (char *)&ypbuf, resultlen); 9020900Swpaul ypbuf[resultlen] = '\0'; 9114639Swpaul free(result); 9214639Swpaul result = (char *)&ypbuf; 9314639Swpaul 94229403Sed if ((cp = strchr(result, '\n'))) 953070Spst *cp = '\0'; 963070Spst 973070Spst cp = strpbrk(result, " \t"); 983070Spst *cp++ = '\0'; 99145633Sume he->h_addr_list = hed->h_addr_ptrs; 100145633Sume he->h_addr = (char *)hed->host_addr; 101145550Sume switch (af) { 102145550Sume case AF_INET: 103145633Sume addrok = inet_aton(result, (struct in_addr *)hed->host_addr); 104145721Sume if (addrok != 1) 105145721Sume break; 106157779Sume if (statp->options & RES_USE_INET6) { 107145721Sume _map_v4v6_address((char *)hed->host_addr, 108145721Sume (char *)hed->host_addr); 109145721Sume af = AF_INET6; 110145721Sume size = NS_IN6ADDRSZ; 111145721Sume } 112145550Sume break; 113145550Sume case AF_INET6: 114145633Sume addrok = inet_pton(af, result, hed->host_addr); 115145550Sume break; 116145550Sume } 117145550Sume if (addrok != 1) { 118157779Sume RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); 119157779Sume return (-1); 120145550Sume } 121145633Sume he->h_addr_list[1] = NULL; 122145633Sume he->h_length = size; 123145633Sume he->h_addrtype = af; 1243070Spst while (*cp == ' ' || *cp == '\t') 1253070Spst cp++; 126145633Sume bp = hed->hostbuf; 127145633Sume ep = hed->hostbuf + sizeof hed->hostbuf; 128145633Sume he->h_name = bp; 129145633Sume q = he->h_aliases = hed->host_aliases; 130145633Sume p = strpbrk(cp, " \t"); 131145633Sume if (p != NULL) 132145633Sume *p++ = '\0'; 133145633Sume size = strlen(cp) + 1; 134145633Sume if (ep - bp < size) { 135157779Sume RES_SET_H_ERRNO(statp, NO_RECOVERY); 136157779Sume return (-1); 137145633Sume } 138145633Sume strlcpy(bp, cp, ep - bp); 139145633Sume bp += size; 140145633Sume cp = p; 1413070Spst while (cp && *cp) { 1423070Spst if (*cp == ' ' || *cp == '\t') { 1433070Spst cp++; 1443070Spst continue; 1453070Spst } 146145633Sume if (q >= &hed->host_aliases[_MAXALIASES - 1]) 147145633Sume break; 148145633Sume p = strpbrk(cp, " \t"); 149145633Sume if (p != NULL) 150145633Sume *p++ = '\0'; 151145633Sume size = strlen(cp) + 1; 152145633Sume if (ep - bp < size) 153145633Sume break; 154145633Sume strlcpy(bp, cp, ep - bp); 155145633Sume *q++ = bp; 156145633Sume bp += size; 157145633Sume cp = p; 1583070Spst } 1593070Spst *q = NULL; 160157779Sume return (0); 16165532Snectar} 162145550Sume 163145633Sumestatic int 164145633Sume_gethostbynisname_r(const char *name, int af, struct hostent *he, 165145633Sume struct hostent_data *hed) 166145550Sume{ 167145550Sume char *map; 168145550Sume 169145550Sume switch (af) { 170145550Sume case AF_INET: 171145550Sume map = "hosts.byname"; 172145550Sume break; 173145550Sume default: 174145550Sume map = "ipnodes.byname"; 175145550Sume break; 176145550Sume } 177157779Sume return (_gethostbynis(name, map, af, he, hed)); 178145550Sume} 179145550Sume 180145633Sumestatic int 181158477Sume_gethostbynisaddr_r(const void *addr, socklen_t len, int af, 182158477Sume struct hostent *he, struct hostent_data *hed) 183145550Sume{ 184145550Sume char *map; 185145677Sume char numaddr[46]; 186145550Sume 187145550Sume switch (af) { 188145550Sume case AF_INET: 189145550Sume map = "hosts.byaddr"; 190145550Sume break; 191145550Sume default: 192145550Sume map = "ipnodes.byaddr"; 193145550Sume break; 194145550Sume } 195145677Sume if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL) 196157779Sume return (-1); 197157779Sume return (_gethostbynis(numaddr, map, af, he, hed)); 198145550Sume} 19965532Snectar#endif /* YP */ 20065532Snectar 20165532Snectarint 20265532Snectar_nis_gethostbyname(void *rval, void *cb_data, va_list ap) 20365532Snectar{ 20465532Snectar#ifdef YP 20517903Speter const char *name; 20617903Speter int af; 207157779Sume char *buffer; 208157779Sume size_t buflen; 209157779Sume int *errnop, *h_errnop; 210157779Sume struct hostent *hptr, he; 211145633Sume struct hostent_data *hed; 212157779Sume res_state statp; 21365532Snectar 21465532Snectar name = va_arg(ap, const char *); 21565532Snectar af = va_arg(ap, int); 216157779Sume hptr = va_arg(ap, struct hostent *); 217157779Sume buffer = va_arg(ap, char *); 218157779Sume buflen = va_arg(ap, size_t); 219157779Sume errnop = va_arg(ap, int *); 220157779Sume h_errnop = va_arg(ap, int *); 22165532Snectar 222157779Sume *((struct hostent **)rval) = NULL; 223157779Sume 224157779Sume statp = __res_state(); 225157779Sume if ((hed = __hostent_data_init()) == NULL) { 226157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 227157779Sume *h_errnop = statp->res_h_errno; 228157779Sume return (NS_NOTFOUND); 229157779Sume } 230157779Sume 231157779Sume if (_gethostbynisname_r(name, af, &he, hed) != 0) { 232157779Sume *h_errnop = statp->res_h_errno; 233157779Sume return (NS_NOTFOUND); 234157779Sume } 235157779Sume if (__copy_hostent(&he, hptr, buffer, buflen) != 0) { 236211276Sume *errnop = errno; 237211276Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 238157779Sume *h_errnop = statp->res_h_errno; 239211276Sume return (NS_RETURN); 240157779Sume } 241157779Sume *((struct hostent **)rval) = hptr; 242157779Sume return (NS_SUCCESS); 24365532Snectar#else 244157779Sume *((struct hostent **)rval) = NULL; 245157779Sume return (NS_UNAVAIL); 24665532Snectar#endif 2473070Spst} 2483070Spst 24965532Snectarint 25065532Snectar_nis_gethostbyaddr(void *rval, void *cb_data, va_list ap) 25165532Snectar{ 25265532Snectar#ifdef YP 253158477Sume const void *addr; 254158477Sume socklen_t len; 25517903Speter int af; 256157779Sume char *buffer; 257157779Sume size_t buflen; 258157779Sume int *errnop, *h_errnop; 259157779Sume struct hostent *hptr, he; 260145633Sume struct hostent_data *hed; 261157779Sume res_state statp; 26265532Snectar 263158477Sume addr = va_arg(ap, const void *); 264158477Sume len = va_arg(ap, socklen_t); 26565532Snectar af = va_arg(ap, int); 266157779Sume hptr = va_arg(ap, struct hostent *); 267157779Sume buffer = va_arg(ap, char *); 268157779Sume buflen = va_arg(ap, size_t); 269157779Sume errnop = va_arg(ap, int *); 270157779Sume h_errnop = va_arg(ap, int *); 271145550Sume 272157779Sume *((struct hostent **)rval) = NULL; 273157779Sume 274157779Sume statp = __res_state(); 275157779Sume if ((hed = __hostent_data_init()) == NULL) { 276157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 277157779Sume *h_errnop = statp->res_h_errno; 278157779Sume return (NS_NOTFOUND); 279157779Sume } 280157779Sume 281157779Sume if (_gethostbynisaddr_r(addr, len, af, &he, hed) != 0) { 282157779Sume *h_errnop = statp->res_h_errno; 283157779Sume return (NS_NOTFOUND); 284157779Sume } 285157779Sume if (__copy_hostent(&he, hptr, buffer, buflen) != 0) { 286211276Sume *errnop = errno; 287211276Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 288157779Sume *h_errnop = statp->res_h_errno; 289211276Sume return (NS_RETURN); 290157779Sume } 291157779Sume *((struct hostent **)rval) = hptr; 292157779Sume return (NS_SUCCESS); 29365532Snectar#else 294157779Sume *((struct hostent **)rval) = NULL; 295157779Sume return (NS_UNAVAIL); 29665532Snectar#endif 2973070Spst} 298