/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <netdb.h>
#include "files_common.h"
#include <string.h>
#include <strings.h>
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <nss.h>
int check_name_host(nss_XbyY_args_t *, const char *, int,
int, const char **, int *, void *, int *);
static char *do_aliases();
static int __nss_files_get_addr(int, const char *, int, void *, int, int *);
static uint_t
{
int i;
for (i = 0; i < namelen; i++) {
}
return (hash);
}
static uint_t
{
int namelen = 0;
/* trim whitespaces */
linelen--;
line++;
}
/* set name when we have our field */
if (field == 1)
/* seek for the end of line or the next whitespace */
linelen--;
line++;
}
/* calculate size of found entry */
if (field == 1) {
break;
}
field--;
}
/* seek for the end of line or the next non-whitespace */
linelen--;
line++;
}
}
int linelen)
{
boolean_t t;
}
uint_t *
int linelen)
{
return (NULL);
hash_arr[0] = 0;
while (has_field &&
hash_arr[0]++;
&has_field);
field++;
}
return (NULL);
}
return (hash_arr);
}
/* convert_ip converts string to appropriate binary form */
int
{
if (*linep == ':')
v6flag++;
linep++;
}
}
static uint_t
int linelen)
{
int h_length;
char *h_addrp;
if (keyhash) {
sizeof (addr_ipv4));
} else {
return (0);
}
/* hash is equal to IPv4 address */
return (hash);
}
/*
* hash_hosts functions are used for single-value attribute
* hash_arr_hosts are used for multi-value attribute (line in local file
* where hostnames can be canonical + aliases)
*/
sizeof (struct hostent),
2,
};
int
{
/* Address */
if (*linep == ':')
v6flag++;
linep++;
}
/* skip the delimiting spaces */
linep++;
/* Canonical name */
keyp++;
linep++;
}
return (1);
}
}
linep++;
/* Aliases */
/* skip the delimiting spaces */
linep++;
/* compare name (case insensitive) */
keyp++;
linep++;
}
/* skip remainder of alias, if any */
linep++;
}
return (0);
}
static int
{
const char *namep;
int namelen;
int i;
&addr_ipv4, &i));
}
static void
{
*namelen = 0;
(*namep)++;
}
(*namep)++;
}
if (**namep == '\0')
return;
(*namelen)++;
}
}
/*
* finish_hostname and add_host_line construct buffer used by nscd
*
* IP1 canonical <aliases>\n
* IP2\n
* IP3\n
* etc.
*/
static int
{
int erange = 0;
char *namep;
int namelen;
char *ap;
int alen;
const char *line;
int linelen;
erange = 1;
} else {
*buffer_end += linelen;
*alias_end = *buffer_end;
**buffer_end = '\0';
(*buflenp)--;
}
} else {
if (erange == 0) {
/* get to the start of alias */
/* see if there's any alias */
alen = 0;
else
erange = 1;
} else {
if (alen != 0) {
/* make room for the aliases */
(void) memmove(
*buffer_end - *alias_end);
/* copy in the alias */
alen);
*buffer_end += alen;
}
/* copy IP */
/* add delimiter */
**buffer_end = '\n';
**buffer_end = '\0';
}
}
}
}
return (erange);
}
{
char *alias_end;
char *buffer;
int buflen;
return (res);
return (NSS_NOTFOUND);
}
return (NSS_SUCCESS);
}
/*
* For non-nscd and libnsl API there is non-hash function with different output.
*/
static nss_status_t
{
/*
* For systems without nscd and for libnsl API there is non-hash
* function with different output buffer.
*/
AF_INET);
else
if (res != NSS_SUCCESS)
return (res);
}
static int
{
return (0);
return (0);
if (v6flag) {
return (0);
} else {
0xffffffffU)
return (0);
}
} else {
return (0);
}
return (1);
}
int
int linelen)
{
int h_length;
char *h_addrp;
/* Compare the address type */
return (0);
/* Retrieve the address */
else
return (0);
/* Compare the address */
}
static int
{
}
static nss_status_t
{
if (res != NSS_SUCCESS)
return (res);
}
/*
* filter_ipv6
*
* Return - NSS_STR_PARSE_SUCCESS: An IPv4 address
* NSS_STR_PARSE_PARSE: An IPv6 address or other errors
*/
static int
int rc;
p = instr;
addrstart = p;
/* parse IP address */
if (*p == ':')
/* IPv6 */
return (NSS_STR_PARSE_PARSE);
else
p++;
}
if (p >= limit)
/* invalid IP */
return (NSS_STR_PARSE_PARSE);
/* extract IP address */
c = *p;
*p = '\0';
*p = c;
if (rc == 0)
/* invalid IP */
return (NSS_STR_PARSE_PARSE);
else
/* IPv4 */
return (NSS_STR_PARSE_SUCCESS);
}
static nss_status_t
{
} else {
/*
* Called by nscd. It does not use in-memory mapped file
* but on-disk file directly.
*/
for (;;) {
/*
* NSS_NOTFOUND, end of file or other errors.
*/
if (rc != NSS_SUCCESS)
break;
/*
* These addresses have to be filtered.
*/
break;
/*
* The entry is an IPv6 address or other errors.
* Skip it and continue to find next one.
*/
}
return (rc);
}
}
};
/*ARGSUSED*/
{
return (_nss_files_constr(host_ops,
&hashinfo, 0));
}
/*
* XXX - this duplicates code from files_common.c because we need to keep
* going after we've found a match to satisfy the multihomed host case.
* It is used only by non-nscd calls.
*/
const char *filter; /* hint for name string */
int type;
{
const char *namep;
char *h_name;
void *addrp;
return (NSS_UNAVAIL);
}
return (res);
return (NSS_UNAVAIL);
} else {
return (NSS_UNAVAIL);
}
res = NSS_NOTFOUND;
h_namelen = 0;
for (;;) {
int linelen;
break; /* EOF */
}
/*
* This check avoids a malloc()/free() for the common
* case. Also, if we're trying to match an alias and an
* already matched entry doesn't share a canonical name
* with the current one, bail.
*/
continue;
}
*last-- = '\0';
;
/* Ignore blank and comment lines */
if (*first == '\0')
continue;
--last;
/* Bail out if the canonical name does not match */
continue;
}
/*
* Still need to check, strcasestr() above is just a hint.
*/
/*
* If we've already matched once and have a possible
* match on this line, copy the aliases where they're
* safe from being overwritten when we look at the
* next entry. They're saved as a string of blank
* separated names for the alias parser. On errors,
* we return failure whether or not we have already
* obtained a valid address.
*/
res = NSS_NOTFOUND;
break;
}
res = NSS_UNAVAIL;
break;
}
abuf_start = abuf;
*abuf = '\0';
res = NSS_NOTFOUND;
break;
}
}
/* inside the application */
if (parsestat != NSS_STR_PARSE_SUCCESS) {
if (parsestat == NSS_STR_PARSE_ERANGE)
continue;
}
} else {
/* nscd call should not be here */
break;
}
/*
* If this is the first one, save the canonical
* name for future matches and continue.
*/
if (++nhosts == 1) {
res = NSS_UNAVAIL;
break;
}
res = NSS_SUCCESS;
if (hp)
continue;
}
/* Extend the array */
ntaddr *= 2;
res = NSS_UNAVAIL;
break;
}
} else {
res = NSS_UNAVAIL;
break;
}
}
}
/*
* For non-nscd, save aliases in a temporary buffer
* Don't have to do this for nscd as 'buffer' already
* contains the required data in the appropriate
* format
*/
if (hp) {
res = NSS_NOTFOUND;
break;
}
}
}
}
/* abuf != NULL implies hp and abuf_start != NULL */
((nhosts + 1) * sizeof (char *) +
}
} else {
sizeof (*addrp6)));
((nhosts + 1) * sizeof (char *) +
sizeof (struct in6_addr));
}
}
res = NSS_NOTFOUND;
} else {
}
}
/*
* Always call _nss_files_endent and ignore args->stayopen because it
* is used only during enumeration.
*/
(void) _nss_files_endent(be, 0);
if (taddr)
if (taddr6)
if (h_name)
if (abuf_start)
return (res);
}
static char *
{
char **cp;
return (abuf);
return (NULL);
}
*abuf++ = ' ';
}
*abuf = '\0';
return (abuf);
}