2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include "files_common.h"
2N/A#include <string.h>
2N/A#include <libtsnet.h>
2N/A#include <netinet/in.h>
2N/A
2N/A/*
2N/A * files/tsol_getrhent.c --
2N/A * "files" backend for nsswitch "tnrhdb" database
2N/A */
2N/Astatic int
2N/Acheck_addr(nss_XbyY_args_t *args, const char *line, int linelen)
2N/A{
2N/A const char *limit, *linep, *keyp;
2N/A char prev;
2N/A int ipv6;
2N/A
2N/A linep = line;
2N/A limit = line + linelen;
2N/A keyp = args->key.hostaddr.addr;
2N/A prev = '\0';
2N/A
2N/A if (strstr(linep, "\\:") != NULL)
2N/A ipv6 = 1;
2N/A else
2N/A ipv6 = 0;
2N/A
2N/A /*
2N/A * compare addr in
2N/A *
2N/A * 192.168.120.6:public
2N/A * fec0\:\:a00\:20ff\:fea0\:21f7:cipso
2N/A *
2N/A * ':' is the separator.
2N/A */
2N/A
2N/A while (*keyp && linep < limit && *keyp == *linep) {
2N/A if ((ipv6 == 0 && *linep == ':') ||
2N/A (ipv6 == 1 && prev != '\\' && *linep == ':'))
2N/A break;
2N/A
2N/A prev = *linep;
2N/A keyp++;
2N/A linep++;
2N/A }
2N/A if (*keyp == '\0' && linep < limit && ((ipv6 == 0 && *linep == ':') ||
2N/A (ipv6 == 1 && prev != '\\' && *linep == ':')))
2N/A return (1);
2N/A
2N/A return (0);
2N/A}
2N/A
2N/Astatic void
2N/Aescape_colon(const char *in, char *out) {
2N/A int i, j;
2N/A for (i = 0, j = 0; in[i] != '\0'; i++) {
2N/A if (in[i] == ':') {
2N/A out[j++] = '\\';
2N/A out[j++] = in[i];
2N/A } else
2N/A out[j++] = in[i];
2N/A }
2N/A out[j] = '\0';
2N/A}
2N/A
2N/Astatic nss_status_t
2N/Agetbyaddr(files_backend_ptr_t be, void *a)
2N/A{
2N/A nss_XbyY_args_t *argp = a;
2N/A char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' */
2N/A const char *addr = NULL;
2N/A nss_status_t rc;
2N/A
2N/A if (argp->key.hostaddr.addr == NULL ||
2N/A (argp->key.hostaddr.type != AF_INET &&
2N/A argp->key.hostaddr.type != AF_INET6))
2N/A return (NSS_NOTFOUND);
2N/A if (strchr(argp->key.hostaddr.addr, ':') != NULL) {
2N/A /* IPV6 */
2N/A if (argp->key.hostaddr.type == AF_INET)
2N/A return (NSS_NOTFOUND);
2N/A escape_colon(argp->key.hostaddr.addr, addr6);
2N/A /* save the key in original format */
2N/A addr = argp->key.hostaddr.addr;
2N/A /* Replace the key with escaped format */
2N/A argp->key.hostaddr.addr = addr6;
2N/A } else {
2N/A /* IPV4 */
2N/A if (argp->key.hostaddr.type == AF_INET6)
2N/A return (NSS_NOTFOUND);
2N/A }
2N/A
2N/A rc = _nss_files_XY_all(be, argp, 1,
2N/A argp->key.hostaddr.addr, check_addr);
2N/A
2N/A /* restore argp->key.hostaddr.addr */
2N/A if (addr)
2N/A argp->key.hostaddr.addr = addr;
2N/A
2N/A return (rc);
2N/A}
2N/A
2N/Astatic files_backend_op_t tsol_rh_ops[] = {
2N/A _nss_files_destr,
2N/A _nss_files_endent,
2N/A _nss_files_setent,
2N/A _nss_files_getent_netdb,
2N/A getbyaddr
2N/A};
2N/A
2N/Anss_backend_t *
2N/A/* LINTED E_FUNC_ARG_UNUSED */
2N/A_nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2,
2N/A/* LINTED E_FUNC_ARG_UNUSED */
2N/A const char *dummy3)
2N/A{
2N/A return (_nss_files_constr(tsol_rh_ops,
2N/A sizeof (tsol_rh_ops) / sizeof (tsol_rh_ops[0]), TNRHDB_PATH,
2N/A NSS_LINELEN_TSOL_RH, NULL, 0));
2N/A}