xref: /illumos-gate/usr/src/lib/nsswitch/files/common/tsol_getrhent.c (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include "files_common.h"
27 #include <string.h>
28 #include <libtsnet.h>
29 #include <netinet/in.h>
30 
31 /*
32  *	files/tsol_getrhent.c --
33  *           "files" backend for nsswitch "tnrhdb" database
34  */
35 static int
check_addr(nss_XbyY_args_t * args,const char * line,int linelen)36 check_addr(nss_XbyY_args_t *args, const char *line, int linelen)
37 {
38 	const char	*limit, *linep, *keyp;
39 	char	prev;
40 	int	ipv6;
41 
42 	linep = line;
43 	limit = line + linelen;
44 	keyp = args->key.hostaddr.addr;
45 	prev = '\0';
46 
47 	if (strstr(linep, "\\:") != NULL)
48 		ipv6 = 1;
49 	else
50 		ipv6 = 0;
51 
52 	/*
53 	 * compare addr in
54 	 *
55 	 * 192.168.120.6:public
56 	 * fec0\:\:a00\:20ff\:fea0\:21f7:cipso
57 	 *
58 	 * ':' is the seperator.
59 	 */
60 
61 	while (*keyp && linep < limit && *keyp == *linep) {
62 		if ((ipv6 == 0 && *linep == ':') ||
63 			(ipv6 == 1 && prev != '\\' && *linep == ':'))
64 			break;
65 
66 		prev = *linep;
67 		keyp++;
68 		linep++;
69 	}
70 	if (*keyp == '\0' && linep < limit && ((ipv6 == 0 && *linep == ':') ||
71 			(ipv6 == 1 && prev != '\\' && *linep == ':')))
72 		return (1);
73 
74 	return (0);
75 }
76 
77 static void
escape_colon(const char * in,char * out)78 escape_colon(const char *in, char *out) {
79 	int i, j;
80 	for (i = 0, j = 0; in[i] != '\0'; i++) {
81 		if (in[i] == ':') {
82 			out[j++] = '\\';
83 			out[j++] = in[i];
84 		} else
85 			out[j++] = in[i];
86 	}
87 	out[j] = '\0';
88 }
89 
90 static nss_status_t
getbyaddr(files_backend_ptr_t be,void * a)91 getbyaddr(files_backend_ptr_t be, void *a)
92 {
93 	nss_XbyY_args_t *argp = a;
94 	char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' */
95 	const char *addr = NULL;
96 	nss_status_t	rc;
97 
98 	if (argp->key.hostaddr.addr == NULL ||
99 		(argp->key.hostaddr.type != AF_INET &&
100 		argp->key.hostaddr.type != AF_INET6))
101 			return (NSS_NOTFOUND);
102 	if (strchr(argp->key.hostaddr.addr, ':') != NULL) {
103 		/* IPV6 */
104 		if (argp->key.hostaddr.type == AF_INET)
105 			return (NSS_NOTFOUND);
106 		escape_colon(argp->key.hostaddr.addr, addr6);
107 		/* save the key in original format */
108 		addr = argp->key.hostaddr.addr;
109 		/* Replace the key with escaped format */
110 		argp->key.hostaddr.addr = addr6;
111 	} else {
112 		/* IPV4 */
113 		if (argp->key.hostaddr.type == AF_INET6)
114 			return (NSS_NOTFOUND);
115 	}
116 
117 	rc = _nss_files_XY_all(be, argp, 1,
118 		argp->key.hostaddr.addr, check_addr);
119 
120 	/* restore argp->key.hostaddr.addr */
121 	if (addr)
122 		argp->key.hostaddr.addr = addr;
123 
124 	return (rc);
125 }
126 
127 static files_backend_op_t tsol_rh_ops[] = {
128 	_nss_files_destr,
129 	_nss_files_endent,
130 	_nss_files_setent,
131 	_nss_files_getent_netdb,
132 	getbyaddr
133 };
134 
135 nss_backend_t *
136 /* LINTED E_FUNC_ARG_UNUSED */
_nss_files_tnrhdb_constr(const char * dummy1,const char * dummy2,const char * dummy3)137 _nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2,
138 /* LINTED E_FUNC_ARG_UNUSED */
139     const char *dummy3)
140 {
141 	return (_nss_files_constr(tsol_rh_ops,
142 	    sizeof (tsol_rh_ops) / sizeof (tsol_rh_ops[0]), TNRHDB_PATH,
143 	    NSS_LINELEN_TSOL_RH, NULL));
144 }
145