xref: /illumos-gate/usr/src/lib/nsswitch/files/common/tsol_getrhent.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include "files_common.h"
29 #include <string.h>
30 #include <libtsnet.h>
31 #include <netinet/in.h>
32 
33 /*
34  *	files/tsol_getrhent.c --
35  *           "files" backend for nsswitch "tnrhdb" database
36  */
37 static int
38 check_addr(nss_XbyY_args_t *args, const char *line, int linelen)
39 {
40 	const char	*limit, *linep, *keyp;
41 	char	prev;
42 	int	ipv6;
43 
44 	linep = line;
45 	limit = line + linelen;
46 	keyp = args->key.hostaddr.addr;
47 	prev = '\0';
48 
49 	if (strstr(linep, "\\:") != NULL)
50 		ipv6 = 1;
51 	else
52 		ipv6 = 0;
53 
54 	/*
55 	 * compare addr in
56 	 *
57 	 * 192.168.120.6:public
58 	 * fec0\:\:a00\:20ff\:fea0\:21f7:cipso
59 	 *
60 	 * ':' is the seperator.
61 	 */
62 
63 	while (*keyp && linep < limit && *keyp == *linep) {
64 		if ((ipv6 == 0 && *linep == ':') ||
65 			(ipv6 == 1 && prev != '\\' && *linep == ':'))
66 			break;
67 
68 		prev = *linep;
69 		keyp++;
70 		linep++;
71 	}
72 	if (*keyp == '\0' && linep < limit && ((ipv6 == 0 && *linep == ':') ||
73 			(ipv6 == 1 && prev != '\\' && *linep == ':')))
74 		return (1);
75 
76 	return (0);
77 }
78 
79 static void
80 escape_colon(const char *in, char *out) {
81 	int i, j;
82 	for (i = 0, j = 0; in[i] != '\0'; i++) {
83 		if (in[i] == ':') {
84 			out[j++] = '\\';
85 			out[j++] = in[i];
86 		} else
87 			out[j++] = in[i];
88 	}
89 	out[j] = '\0';
90 }
91 
92 static nss_status_t
93 getbyaddr(files_backend_ptr_t be, void *a)
94 {
95 	nss_XbyY_args_t *argp = a;
96 	char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' */
97 	const char *addr = NULL;
98 	nss_status_t	rc;
99 
100 	if (argp->key.hostaddr.addr == NULL ||
101 		(argp->key.hostaddr.type != AF_INET &&
102 		argp->key.hostaddr.type != AF_INET6))
103 			return (NSS_NOTFOUND);
104 	if (strchr(argp->key.hostaddr.addr, ':') != NULL) {
105 		/* IPV6 */
106 		if (argp->key.hostaddr.type == AF_INET)
107 			return (NSS_NOTFOUND);
108 		escape_colon(argp->key.hostaddr.addr, addr6);
109 		/* save the key in original format */
110 		addr = argp->key.hostaddr.addr;
111 		/* Replace the key with escaped format */
112 		argp->key.hostaddr.addr = addr6;
113 	} else {
114 		/* IPV4 */
115 		if (argp->key.hostaddr.type == AF_INET6)
116 			return (NSS_NOTFOUND);
117 	}
118 
119 	rc = _nss_files_XY_all(be, argp, 1,
120 		argp->key.hostaddr.addr, check_addr);
121 
122 	/* restore argp->key.hostaddr.addr */
123 	if (addr)
124 		argp->key.hostaddr.addr = addr;
125 
126 	return (rc);
127 }
128 
129 static files_backend_op_t tsol_rh_ops[] = {
130 	_nss_files_destr,
131 	_nss_files_endent,
132 	_nss_files_setent,
133 	_nss_files_getent_netdb,
134 	getbyaddr
135 };
136 
137 nss_backend_t *
138 /* LINTED E_FUNC_ARG_UNUSED */
139 _nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2,
140 /* LINTED E_FUNC_ARG_UNUSED */
141     const char *dummy3)
142 {
143 	return (_nss_files_constr(tsol_rh_ops,
144 	    sizeof (tsol_rh_ops) / sizeof (tsol_rh_ops[0]), TNRHDB_PATH,
145 	    NSS_LINELEN_TSOL_RH, NULL));
146 }
147