diff options
Diffstat (limited to 'nss/nss_files/files-hosts.c')
-rw-r--r-- | nss/nss_files/files-hosts.c | 482 |
1 files changed, 0 insertions, 482 deletions
diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c deleted file mode 100644 index bccb6a5780..0000000000 --- a/nss/nss_files/files-hosts.c +++ /dev/null @@ -1,482 +0,0 @@ -/* Hosts file parser in nss_files module. - Copyright (C) 1996-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> -#include <netdb.h> -#include <resolv/resolv-internal.h> - - -/* Get implementation for some internal functions. */ -#include "../resolv/mapv4v6addr.h" -#include "../resolv/res_hconf.h" - - -#define ENTNAME hostent -#define DATABASE "hosts" -#define NEED_H_ERRNO - -#define EXTRA_ARGS , af, flags -#define EXTRA_ARGS_DECL , int af, int flags - -#define ENTDATA hostent_data -struct hostent_data - { - unsigned char host_addr[16]; /* IPv4 or IPv6 address. */ - char *h_addr_ptrs[2]; /* Points to that and null terminator. */ - }; - -#define TRAILING_LIST_MEMBER h_aliases -#define TRAILING_LIST_SEPARATOR_P isspace -#include "files-parse.c" -LINE_PARSER -("#", - { - char *addr; - - STRING_FIELD (addr, isspace, 1); - - /* Parse address. */ - if (inet_pton (af == AF_UNSPEC ? AF_INET : af, addr, entdata->host_addr) - > 0) - af = af == AF_UNSPEC ? AF_INET : af; - else - { - if (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 - && inet_pton (AF_INET, addr, entdata->host_addr) > 0) - map_v4v6_address ((char *) entdata->host_addr, - (char *) entdata->host_addr); - else if (af == AF_INET - && inet_pton (AF_INET6, addr, entdata->host_addr) > 0) - { - if (IN6_IS_ADDR_V4MAPPED (entdata->host_addr)) - memcpy (entdata->host_addr, entdata->host_addr + 12, INADDRSZ); - else if (IN6_IS_ADDR_LOOPBACK (entdata->host_addr)) - { - in_addr_t localhost = htonl (INADDR_LOOPBACK); - memcpy (entdata->host_addr, &localhost, sizeof (localhost)); - } - else - /* Illegal address: ignore line. */ - return 0; - } - else if (af == AF_UNSPEC - && inet_pton (AF_INET6, addr, entdata->host_addr) > 0) - af = AF_INET6; - else - /* Illegal address: ignore line. */ - return 0; - } - - /* We always return entries of the requested form. */ - result->h_addrtype = af; - result->h_length = af == AF_INET ? INADDRSZ : IN6ADDRSZ; - - /* Store a pointer to the address in the expected form. */ - entdata->h_addr_ptrs[0] = (char *) entdata->host_addr; - entdata->h_addr_ptrs[1] = NULL; - result->h_addr_list = entdata->h_addr_ptrs; - - STRING_FIELD (result->h_name, isspace, 1); - }) - -#define EXTRA_ARGS_VALUE \ - , (res_use_inet6 () ? AF_INET6 : AF_INET), \ - (res_use_inet6 () ? AI_V4MAPPED : 0) -#include "files-XXX.c" -#undef EXTRA_ARGS_VALUE - -/* We only need to consider IPv4 mapped addresses if the input to the - gethostbyaddr() function is an IPv6 address. */ -#define EXTRA_ARGS_VALUE \ - , af, (len == IN6ADDRSZ ? AI_V4MAPPED : 0) -DB_LOOKUP (hostbyaddr, ,,, - { - if (result->h_length == (int) len - && ! memcmp (addr, result->h_addr_list[0], len)) - break; - }, const void *addr, socklen_t len, int af) -#undef EXTRA_ARGS_VALUE - -enum nss_status -_nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result, - char *buffer, size_t buflen, int *errnop, - int *herrnop, int32_t *ttlp, char **canonp) -{ - FILE *stream = NULL; - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data); - buffer += pad; - buflen = buflen > pad ? buflen - pad : 0; - - /* Open file. */ - enum nss_status status = internal_setent (&stream); - - if (status == NSS_STATUS_SUCCESS) - { - /* XXX Is using _res to determine whether we want to convert IPv4 - addresses to IPv6 addresses really the right thing to do? */ - int flags = (res_use_inet6 () ? AI_V4MAPPED : 0); - - while ((status = internal_getent (stream, result, buffer, buflen, errnop, - herrnop, af, flags)) - == NSS_STATUS_SUCCESS) - { - LOOKUP_NAME_CASE (h_name, h_aliases) - } - - if (status == NSS_STATUS_SUCCESS - && _res_hconf.flags & HCONF_FLAG_MULTI) - { - /* We have to get all host entries from the file. */ - size_t tmp_buflen = MIN (buflen, 4096); - char tmp_buffer_stack[tmp_buflen] - __attribute__ ((__aligned__ (__alignof__ (struct hostent_data)))); - char *tmp_buffer = tmp_buffer_stack; - struct hostent tmp_result_buf; - int naddrs = 1; - int naliases = 0; - char *bufferend; - bool tmp_buffer_malloced = false; - - while (result->h_aliases[naliases] != NULL) - ++naliases; - - bufferend = (char *) &result->h_aliases[naliases + 1]; - - again: - while ((status = internal_getent (stream, &tmp_result_buf, tmp_buffer, - tmp_buflen, errnop, herrnop, af, - flags)) - == NSS_STATUS_SUCCESS) - { - int matches = 1; - struct hostent *old_result = result; - result = &tmp_result_buf; - /* The following piece is a bit clumsy but we want to use the - `LOOKUP_NAME_CASE' value. The optimizer should do its - job. */ - do - { - LOOKUP_NAME_CASE (h_name, h_aliases) - result = old_result; - } - while ((matches = 0)); - - if (matches) - { - /* We could be very clever and try to recycle a few bytes - in the buffer instead of generating new arrays. But - we are not doing this here since it's more work than - it's worth. Simply let the user provide a bit bigger - buffer. */ - char **new_h_addr_list; - char **new_h_aliases; - int newaliases = 0; - size_t newstrlen = 0; - int cnt; - - /* Count the new aliases and the length of the strings. */ - while (tmp_result_buf.h_aliases[newaliases] != NULL) - { - char *cp = tmp_result_buf.h_aliases[newaliases]; - ++newaliases; - newstrlen += strlen (cp) + 1; - } - /* If the real name is different add it also to the - aliases. This means that there is a duplication - in the alias list but this is really the user's - problem. */ - if (strcmp (old_result->h_name, - tmp_result_buf.h_name) != 0) - { - ++newaliases; - newstrlen += strlen (tmp_result_buf.h_name) + 1; - } - - /* Make sure bufferend is aligned. */ - assert ((bufferend - (char *) 0) % sizeof (char *) == 0); - - /* Now we can check whether the buffer is large enough. - 16 is the maximal size of the IP address. */ - if (bufferend + 16 + (naddrs + 2) * sizeof (char *) - + roundup (newstrlen, sizeof (char *)) - + (naliases + newaliases + 1) * sizeof (char *) - >= buffer + buflen) - { - *errnop = ERANGE; - *herrnop = NETDB_INTERNAL; - status = NSS_STATUS_TRYAGAIN; - goto out; - } - - new_h_addr_list = - (char **) (bufferend - + roundup (newstrlen, sizeof (char *)) - + 16); - new_h_aliases = - (char **) ((char *) new_h_addr_list - + (naddrs + 2) * sizeof (char *)); - - /* Copy the old data in the new arrays. */ - for (cnt = 0; cnt < naddrs; ++cnt) - new_h_addr_list[cnt] = old_result->h_addr_list[cnt]; - - for (cnt = 0; cnt < naliases; ++cnt) - new_h_aliases[cnt] = old_result->h_aliases[cnt]; - - /* Store the new strings. */ - cnt = 0; - while (tmp_result_buf.h_aliases[cnt] != NULL) - { - new_h_aliases[naliases++] = bufferend; - bufferend = (__stpcpy (bufferend, - tmp_result_buf.h_aliases[cnt]) - + 1); - ++cnt; - } - - if (cnt < newaliases) - { - new_h_aliases[naliases++] = bufferend; - bufferend = __stpcpy (bufferend, - tmp_result_buf.h_name) + 1; - } - - /* Final NULL pointer. */ - new_h_aliases[naliases] = NULL; - - /* Round up the buffer end address. */ - bufferend += (sizeof (char *) - - ((bufferend - (char *) 0) - % sizeof (char *))) % sizeof (char *); - - /* Now the new address. */ - new_h_addr_list[naddrs++] = - memcpy (bufferend, tmp_result_buf.h_addr, - tmp_result_buf.h_length); - - /* Also here a final NULL pointer. */ - new_h_addr_list[naddrs] = NULL; - - /* Store the new array pointers. */ - old_result->h_aliases = new_h_aliases; - old_result->h_addr_list = new_h_addr_list; - - /* Compute the new buffer end. */ - bufferend = (char *) &new_h_aliases[naliases + 1]; - assert (bufferend <= buffer + buflen); - - result = old_result; - } - } - - if (status == NSS_STATUS_TRYAGAIN) - { - size_t newsize = 2 * tmp_buflen; - if (tmp_buffer_malloced) - { - char *newp = realloc (tmp_buffer, newsize); - if (newp != NULL) - { - assert ((((uintptr_t) newp) - & (__alignof__ (struct hostent_data) - 1)) - == 0); - tmp_buffer = newp; - tmp_buflen = newsize; - goto again; - } - } - else if (!__libc_use_alloca (buflen + newsize)) - { - tmp_buffer = malloc (newsize); - if (tmp_buffer != NULL) - { - assert ((((uintptr_t) tmp_buffer) - & (__alignof__ (struct hostent_data) - 1)) - == 0); - tmp_buffer_malloced = true; - tmp_buflen = newsize; - goto again; - } - } - else - { - tmp_buffer - = extend_alloca (tmp_buffer, tmp_buflen, - newsize - + __alignof__ (struct hostent_data)); - tmp_buffer = (char *) (((uintptr_t) tmp_buffer - + __alignof__ (struct hostent_data) - - 1) - & ~(__alignof__ (struct hostent_data) - - 1)); - goto again; - } - } - else - status = NSS_STATUS_SUCCESS; - out: - if (tmp_buffer_malloced) - free (tmp_buffer); - } - - internal_endent (&stream); - } - - if (canonp && status == NSS_STATUS_SUCCESS) - *canonp = result->h_name; - - return status; -} - -enum nss_status -_nss_files_gethostbyname_r (const char *name, struct hostent *result, - char *buffer, size_t buflen, int *errnop, - int *herrnop) -{ - int af = (res_use_inet6 () ? AF_INET6 : AF_INET); - - return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen, - errnop, herrnop, NULL, NULL); -} - -enum nss_status -_nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result, - char *buffer, size_t buflen, int *errnop, - int *herrnop) -{ - return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen, - errnop, herrnop, NULL, NULL); -} - -enum nss_status -_nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, - char *buffer, size_t buflen, int *errnop, - int *herrnop, int32_t *ttlp) -{ - FILE *stream = NULL; - - /* Open file. */ - enum nss_status status = internal_setent (&stream); - - if (status == NSS_STATUS_SUCCESS) - { - bool any = false; - bool got_canon = false; - while (1) - { - /* Align the buffer for the next record. */ - uintptr_t pad = (-(uintptr_t) buffer - % __alignof__ (struct hostent_data)); - buffer += pad; - buflen = buflen > pad ? buflen - pad : 0; - - struct hostent result; - status = internal_getent (stream, &result, buffer, buflen, errnop, - herrnop, AF_UNSPEC, 0); - if (status != NSS_STATUS_SUCCESS) - break; - - int naliases = 0; - if (__strcasecmp (name, result.h_name) != 0) - { - for (; result.h_aliases[naliases] != NULL; ++naliases) - if (! __strcasecmp (name, result.h_aliases[naliases])) - break; - if (result.h_aliases[naliases] == NULL) - continue; - - /* We know this alias exist. Count it. */ - ++naliases; - } - - /* Determine how much memory has been used so far. */ - // XXX It is not necessary to preserve the aliases array - while (result.h_aliases[naliases] != NULL) - ++naliases; - char *bufferend = (char *) &result.h_aliases[naliases + 1]; - assert (buflen >= bufferend - buffer); - buflen -= bufferend - buffer; - buffer = bufferend; - - /* We found something. */ - any = true; - - /* Create the record the caller expects. There is only one - address. */ - assert (result.h_addr_list[1] == NULL); - if (*pat == NULL) - { - uintptr_t pad = (-(uintptr_t) buffer - % __alignof__ (struct gaih_addrtuple)); - buffer += pad; - buflen = buflen > pad ? buflen - pad : 0; - - if (__builtin_expect (buflen < sizeof (struct gaih_addrtuple), - 0)) - { - *errnop = ERANGE; - *herrnop = NETDB_INTERNAL; - status = NSS_STATUS_TRYAGAIN; - break; - } - - *pat = (struct gaih_addrtuple *) buffer; - buffer += sizeof (struct gaih_addrtuple); - buflen -= sizeof (struct gaih_addrtuple); - } - - (*pat)->next = NULL; - (*pat)->name = got_canon ? NULL : result.h_name; - got_canon = true; - (*pat)->family = result.h_addrtype; - memcpy ((*pat)->addr, result.h_addr_list[0], result.h_length); - (*pat)->scopeid = 0; - - pat = &((*pat)->next); - - /* If we only look for the first matching entry we are done. */ - if ((_res_hconf.flags & HCONF_FLAG_MULTI) == 0) - break; - } - - /* If we have to look for multiple records and found one, this - is a success. */ - if (status == NSS_STATUS_NOTFOUND && any) - { - assert ((_res_hconf.flags & HCONF_FLAG_MULTI) != 0); - status = NSS_STATUS_SUCCESS; - } - - internal_endent (&stream); - } - else if (status == NSS_STATUS_TRYAGAIN) - { - *errnop = errno; - *herrnop = TRY_AGAIN; - } - else - { - *errnop = errno; - *herrnop = NO_DATA; - } - - return status; -} |