11676Sjpk /*
21676Sjpk * CDDL HEADER START
31676Sjpk *
41676Sjpk * The contents of this file are subject to the terms of the
51676Sjpk * Common Development and Distribution License (the "License").
61676Sjpk * You may not use this file except in compliance with the License.
71676Sjpk *
81676Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91676Sjpk * or http://www.opensolaris.org/os/licensing.
101676Sjpk * See the License for the specific language governing permissions
111676Sjpk * and limitations under the License.
121676Sjpk *
131676Sjpk * When distributing Covered Code, include this CDDL HEADER in each
141676Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151676Sjpk * If applicable, add the following below this CDDL HEADER, with the
161676Sjpk * fields enclosed by brackets "[]" replaced with your own identifying
171676Sjpk * information: Portions Copyright [yyyy] [name of copyright owner]
181676Sjpk *
191676Sjpk * CDDL HEADER END
201676Sjpk */
211676Sjpk /*
221676Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
231676Sjpk * Use is subject to license terms.
241676Sjpk */
251676Sjpk
261676Sjpk #pragma ident "%Z%%M% %I% %E% SMI"
271676Sjpk
281676Sjpk #include "files_common.h"
291676Sjpk #include <string.h>
301676Sjpk #include <libtsnet.h>
31*2830Sdjl #include <netinet/in.h>
321676Sjpk
331676Sjpk /*
341676Sjpk * files/tsol_getrhent.c --
351676Sjpk * "files" backend for nsswitch "tnrhdb" database
361676Sjpk */
371676Sjpk static int
check_addr(nss_XbyY_args_t * args,const char * line,int linelen)38*2830Sdjl check_addr(nss_XbyY_args_t *args, const char *line, int linelen)
391676Sjpk {
40*2830Sdjl const char *limit, *linep, *keyp;
41*2830Sdjl char prev;
42*2830Sdjl int ipv6;
43*2830Sdjl
44*2830Sdjl linep = line;
45*2830Sdjl limit = line + linelen;
46*2830Sdjl keyp = args->key.hostaddr.addr;
47*2830Sdjl prev = '\0';
48*2830Sdjl
49*2830Sdjl if (strstr(linep, "\\:") != NULL)
50*2830Sdjl ipv6 = 1;
51*2830Sdjl else
52*2830Sdjl ipv6 = 0;
531676Sjpk
54*2830Sdjl /*
55*2830Sdjl * compare addr in
56*2830Sdjl *
57*2830Sdjl * 192.168.120.6:public
58*2830Sdjl * fec0\:\:a00\:20ff\:fea0\:21f7:cipso
59*2830Sdjl *
60*2830Sdjl * ':' is the seperator.
61*2830Sdjl */
62*2830Sdjl
63*2830Sdjl while (*keyp && linep < limit && *keyp == *linep) {
64*2830Sdjl if ((ipv6 == 0 && *linep == ':') ||
65*2830Sdjl (ipv6 == 1 && prev != '\\' && *linep == ':'))
66*2830Sdjl break;
67*2830Sdjl
68*2830Sdjl prev = *linep;
69*2830Sdjl keyp++;
70*2830Sdjl linep++;
71*2830Sdjl }
72*2830Sdjl if (*keyp == '\0' && linep < limit && ((ipv6 == 0 && *linep == ':') ||
73*2830Sdjl (ipv6 == 1 && prev != '\\' && *linep == ':')))
741676Sjpk return (1);
751676Sjpk
761676Sjpk return (0);
771676Sjpk }
781676Sjpk
79*2830Sdjl static void
escape_colon(const char * in,char * out)80*2830Sdjl escape_colon(const char *in, char *out) {
81*2830Sdjl int i, j;
82*2830Sdjl for (i = 0, j = 0; in[i] != '\0'; i++) {
83*2830Sdjl if (in[i] == ':') {
84*2830Sdjl out[j++] = '\\';
85*2830Sdjl out[j++] = in[i];
86*2830Sdjl } else
87*2830Sdjl out[j++] = in[i];
88*2830Sdjl }
89*2830Sdjl out[j] = '\0';
90*2830Sdjl }
91*2830Sdjl
921676Sjpk static nss_status_t
getbyaddr(files_backend_ptr_t be,void * a)931676Sjpk getbyaddr(files_backend_ptr_t be, void *a)
941676Sjpk {
951676Sjpk nss_XbyY_args_t *argp = a;
96*2830Sdjl char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' */
97*2830Sdjl const char *addr = NULL;
98*2830Sdjl nss_status_t rc;
991676Sjpk
100*2830Sdjl if (argp->key.hostaddr.addr == NULL ||
101*2830Sdjl (argp->key.hostaddr.type != AF_INET &&
102*2830Sdjl argp->key.hostaddr.type != AF_INET6))
103*2830Sdjl return (NSS_NOTFOUND);
104*2830Sdjl if (strchr(argp->key.hostaddr.addr, ':') != NULL) {
105*2830Sdjl /* IPV6 */
106*2830Sdjl if (argp->key.hostaddr.type == AF_INET)
107*2830Sdjl return (NSS_NOTFOUND);
108*2830Sdjl escape_colon(argp->key.hostaddr.addr, addr6);
109*2830Sdjl /* save the key in original format */
110*2830Sdjl addr = argp->key.hostaddr.addr;
111*2830Sdjl /* Replace the key with escaped format */
112*2830Sdjl argp->key.hostaddr.addr = addr6;
113*2830Sdjl } else {
114*2830Sdjl /* IPV4 */
115*2830Sdjl if (argp->key.hostaddr.type == AF_INET6)
116*2830Sdjl return (NSS_NOTFOUND);
117*2830Sdjl }
118*2830Sdjl
119*2830Sdjl rc = _nss_files_XY_all(be, argp, 1,
120*2830Sdjl argp->key.hostaddr.addr, check_addr);
121*2830Sdjl
122*2830Sdjl /* restore argp->key.hostaddr.addr */
123*2830Sdjl if (addr)
124*2830Sdjl argp->key.hostaddr.addr = addr;
125*2830Sdjl
126*2830Sdjl return (rc);
1271676Sjpk }
1281676Sjpk
1291676Sjpk static files_backend_op_t tsol_rh_ops[] = {
1301676Sjpk _nss_files_destr,
1311676Sjpk _nss_files_endent,
1321676Sjpk _nss_files_setent,
1331676Sjpk _nss_files_getent_netdb,
1341676Sjpk getbyaddr
1351676Sjpk };
1361676Sjpk
1371676Sjpk nss_backend_t *
138*2830Sdjl /* LINTED E_FUNC_ARG_UNUSED */
_nss_files_tnrhdb_constr(const char * dummy1,const char * dummy2,const char * dummy3)1391676Sjpk _nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2,
140*2830Sdjl /* LINTED E_FUNC_ARG_UNUSED */
1411676Sjpk const char *dummy3)
1421676Sjpk {
1431676Sjpk return (_nss_files_constr(tsol_rh_ops,
1441676Sjpk sizeof (tsol_rh_ops) / sizeof (tsol_rh_ops[0]), TNRHDB_PATH,
1451676Sjpk NSS_LINELEN_TSOL_RH, NULL));
1461676Sjpk }
147