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 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 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 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 */ 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