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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * From "tsol_getrhent.c 7.6 00/09/22 SMI; TSOL 2.x" 26 */ 27 28 #include <stdio.h> 29 #include <nss_dbdefs.h> 30 #include <libtsnet.h> 31 #include <sys/types.h> 32 #include <sys/socket.h> 33 #include <netinet/in.h> 34 #include <arpa/inet.h> 35 #include <string.h> 36 #include <secdb.h> 37 #include <nss.h> 38 #include <libtsnet.h> 39 #include <libintl.h> 40 41 extern void _nss_XbyY_fgets(FILE *, nss_XbyY_args_t *); /* from lib.c */ 42 43 static int tsol_rh_stayopen; /* Unsynchronized, but it affects only */ 44 /* efficiency, not correctness */ 45 static DEFINE_NSS_DB_ROOT(db_root); 46 static DEFINE_NSS_GETENT(context); 47 48 static void 49 _nss_initf_tsol_rh(nss_db_params_t *p) 50 { 51 p->name = NSS_DBNAM_TSOL_RH; 52 p->default_config = NSS_DEFCONF_TSOL_RH; 53 } 54 55 tsol_rhent_t * 56 tsol_getrhbyaddr(const void *addrp, size_t len, int af) 57 { 58 int err = 0; 59 char *errstr = NULL; 60 char buf[NSS_BUFLEN_TSOL_RH]; 61 tsol_rhstr_t result; 62 tsol_rhstr_t *rhstrp = NULL; 63 nss_XbyY_args_t arg; 64 65 NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr); 66 67 arg.key.hostaddr.addr = (const char *)addrp; 68 arg.key.hostaddr.len = len; 69 arg.key.hostaddr.type = af; 70 arg.stayopen = tsol_rh_stayopen; 71 arg.h_errno = TSOL_NOT_FOUND; 72 arg.status = nss_search(&db_root, _nss_initf_tsol_rh, 73 NSS_DBOP_TSOL_RH_BYADDR, &arg); 74 rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg); 75 76 #ifdef DEBUG 77 (void) fprintf(stdout, "tsol_getrhbyaddr %s: %s\n", 78 (char *)addrp, rhstrp ? rhstrp->template : "NULL"); 79 #endif /* DEBUG */ 80 81 if (rhstrp == NULL) 82 return (NULL); 83 84 return (rhstr_to_ent(rhstrp, &err, &errstr)); 85 } 86 87 void 88 tsol_setrhent(int stay) 89 { 90 tsol_rh_stayopen |= stay; 91 nss_setent(&db_root, _nss_initf_tsol_rh, &context); 92 } 93 94 void 95 tsol_endrhent(void) 96 { 97 tsol_rh_stayopen = 0; 98 nss_endent(&db_root, _nss_initf_tsol_rh, &context); 99 nss_delete(&db_root); 100 } 101 102 tsol_rhent_t * 103 tsol_getrhent(void) 104 { 105 int err = 0; 106 char *errstr = NULL; 107 char buf[NSS_BUFLEN_TSOL_RH]; 108 tsol_rhstr_t result; 109 tsol_rhstr_t *rhstrp = NULL; 110 nss_XbyY_args_t arg; 111 112 NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr); 113 /* No key, no stayopen */ 114 arg.status = nss_getent(&db_root, _nss_initf_tsol_rh, &context, &arg); 115 rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg); 116 117 #ifdef DEBUG 118 (void) fprintf(stdout, "tsol_getrhent: %s\n", 119 rhstrp ? rhstrp->template : "NULL"); 120 #endif /* DEBUG */ 121 122 if (rhstrp == NULL) 123 return (NULL); 124 125 return (rhstr_to_ent(rhstrp, &err, &errstr)); 126 } 127 128 tsol_rhent_t * 129 tsol_fgetrhent(FILE *f, boolean_t *error) 130 { 131 int err = 0; 132 char *errstr = NULL; 133 char buf[NSS_BUFLEN_TSOL_RH]; 134 tsol_rhstr_t result; 135 tsol_rhstr_t *rhstrp = NULL; 136 tsol_rhent_t *rhentp = NULL; 137 nss_XbyY_args_t arg; 138 139 NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr); 140 _nss_XbyY_fgets(f, &arg); 141 rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg); 142 if (rhstrp == NULL) 143 return (NULL); 144 rhentp = rhstr_to_ent(rhstrp, &err, &errstr); 145 while (rhentp == NULL) { 146 /* 147 * Loop until we find a non-blank, non-comment line, or 148 * until EOF. No need to log blank lines, comments. 149 */ 150 if (err != LTSNET_EMPTY) { 151 (void) fprintf(stderr, "%s: %.32s%s: %s\n", 152 gettext("Error parsing tnrhdb file"), errstr, 153 (strlen(errstr) > 32)? "...": "", 154 (char *)tsol_strerror(err, errno)); 155 *error = B_TRUE; 156 } 157 _nss_XbyY_fgets(f, &arg); 158 rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg); 159 if (rhstrp == NULL) /* EOF */ 160 return (NULL); 161 rhentp = rhstr_to_ent(rhstrp, &err, &errstr); 162 } 163 return (rhentp); 164 } 165 166 /* 167 * This is the callback routine for nss. 168 */ 169 int 170 str_to_rhstr(const char *instr, int lenstr, void *entp, char *buffer, 171 int buflen) 172 { 173 int len; 174 char *str = NULL; 175 char *last = NULL; 176 char *sep = KV_TOKEN_DELIMIT; 177 tsol_rhstr_t *rhstrp = (tsol_rhstr_t *)entp; 178 179 if ((instr >= buffer && (buffer + buflen) > instr) || 180 (buffer >= instr && (instr + lenstr) > buffer)) 181 return (NSS_STR_PARSE_PARSE); 182 if (lenstr >= buflen) 183 return (NSS_STR_PARSE_ERANGE); 184 (void) strncpy(buffer, instr, buflen); 185 str = _strtok_escape(buffer, sep, &last); 186 rhstrp->address = _do_unescape(str); 187 /* 188 * _do_unesape uses isspace() which removes "\n". 189 * we keep "\n" as we use it in checking for 190 * blank lines. 191 */ 192 if (strcmp(instr, "\n") == 0) 193 rhstrp->address = "\n"; 194 rhstrp->template = _strtok_escape(NULL, sep, &last); 195 if (rhstrp->template != NULL) { 196 len = strlen(rhstrp->template); 197 if (rhstrp->template[len - 1] == '\n') 198 rhstrp->template[len - 1] = '\0'; 199 } 200 if (rhstrp->address == NULL) 201 rhstrp->family = 0; 202 else if (strchr(rhstrp->address, ':') == NULL) 203 rhstrp->family = AF_INET; 204 else 205 rhstrp->family = AF_INET6; 206 207 #ifdef DEBUG 208 (void) fprintf(stdout, 209 "str_to_rhstr:str - %s\taddress - %s\n\ttemplate - %s\n", 210 instr, rhstrp->address ? rhstrp->address : "NULL", 211 rhstrp->template ? rhstrp->template : "NULL"); 212 #endif /* DEBUG */ 213 214 return (NSS_STR_PARSE_SUCCESS); 215 } 216 217 tsol_host_type_t 218 tsol_getrhtype(char *rhost) { 219 int herr; 220 struct hostent *hp; 221 in6_addr_t in6; 222 char abuf[INET6_ADDRSTRLEN]; 223 tsol_rhent_t rhent; 224 tsol_tpent_t tp; 225 226 if ((hp = getipnodebyname(rhost, AF_INET6, 227 AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &herr)) == NULL) { 228 return (UNLABELED); 229 } 230 231 (void) memset(&rhent, 0, sizeof (rhent)); 232 (void) memcpy(&in6, hp->h_addr, hp->h_length); 233 234 if (IN6_IS_ADDR_V4MAPPED(&in6)) { 235 rhent.rh_address.ta_family = AF_INET; 236 IN6_V4MAPPED_TO_INADDR(&in6, &rhent.rh_address.ta_addr_v4); 237 (void) inet_ntop(AF_INET, &rhent.rh_address.ta_addr_v4, abuf, 238 sizeof (abuf)); 239 } else { 240 rhent.rh_address.ta_family = AF_INET6; 241 rhent.rh_address.ta_addr_v6 = in6; 242 (void) inet_ntop(AF_INET6, &in6, abuf, sizeof (abuf)); 243 } 244 245 if (tnrh(TNDB_GET, &rhent) != 0) 246 return (UNLABELED); 247 248 if (rhent.rh_template[0] == '\0') 249 return (UNLABELED); 250 251 (void) strlcpy(tp.name, rhent.rh_template, sizeof (tp.name)); 252 253 if (tnrhtp(TNDB_GET, &tp) != 0) 254 return (UNLABELED); 255 256 return (tp.host_type); 257 } 258