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
check_addr(nss_XbyY_args_t * args,const char * line,int linelen)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
escape_colon(const char * in,char * out)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
getbyaddr(files_backend_ptr_t be,void * a)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 */
_nss_files_tnrhdb_constr(const char * dummy1,const char * dummy2,const char * dummy3)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