xref: /onnv-gate/usr/src/lib/nsswitch/files/common/tsol_getrhent.c (revision 2830:5228d1267a01)
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