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