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 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Rentrant (MT-safe) getrpcYY interfaces. 29 */ 30 31 #include "mt.h" 32 #include <ctype.h> 33 #include <nss_dbdefs.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <rpc/rpcent.h> 37 38 extern int str2rpcent(const char *, int, void *, char *, int); 39 40 static int rpc_stayopen; /* Unsynchronized, but it affects only */ 41 /* efficiency, not correctness */ 42 static DEFINE_NSS_DB_ROOT(db_root); 43 static DEFINE_NSS_GETENT(context); 44 45 void 46 _nss_initf_rpc(nss_db_params_t *p) 47 { 48 p->name = NSS_DBNAM_RPC; 49 p->default_config = NSS_DEFCONF_RPC; 50 } 51 52 struct rpcent * 53 getrpcbyname_r(const char *name, struct rpcent *result, char *buffer, 54 int buflen) 55 { 56 nss_XbyY_args_t arg; 57 nss_status_t res; 58 59 if (name == (const char *)NULL) { 60 errno = ERANGE; 61 return (NULL); 62 } 63 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2rpcent); 64 arg.key.name = name; 65 arg.stayopen = rpc_stayopen; 66 res = nss_search(&db_root, _nss_initf_rpc, 67 NSS_DBOP_RPC_BYNAME, &arg); 68 arg.status = res; 69 return ((struct rpcent *)NSS_XbyY_FINI(&arg)); 70 } 71 72 struct rpcent * 73 getrpcbynumber_r(const int number, struct rpcent *result, char *buffer, 74 int buflen) 75 { 76 nss_XbyY_args_t arg; 77 nss_status_t res; 78 79 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2rpcent); 80 arg.key.number = number; 81 arg.stayopen = rpc_stayopen; 82 res = nss_search(&db_root, _nss_initf_rpc, 83 NSS_DBOP_RPC_BYNUMBER, &arg); 84 arg.status = res; 85 return ((struct rpcent *)NSS_XbyY_FINI(&arg)); 86 } 87 88 void 89 setrpcent(const int stay) 90 { 91 rpc_stayopen |= stay; 92 nss_setent(&db_root, _nss_initf_rpc, &context); 93 } 94 95 void 96 endrpcent(void) 97 { 98 rpc_stayopen = 0; 99 nss_endent(&db_root, _nss_initf_rpc, &context); 100 nss_delete(&db_root); 101 } 102 103 struct rpcent * 104 getrpcent_r(struct rpcent *result, char *buffer, int buflen) 105 { 106 nss_XbyY_args_t arg; 107 nss_status_t res; 108 109 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2rpcent); 110 /* No key, no stayopen */ 111 res = nss_getent(&db_root, _nss_initf_rpc, &context, &arg); 112 arg.status = res; 113 return ((struct rpcent *)NSS_XbyY_FINI(&arg)); 114 } 115 116 int 117 str2rpcent(const char *instr, int lenstr, void *ent, char *buffer, int buflen) 118 { 119 struct rpcent *rpc = (struct rpcent *)ent; 120 const char *p, *numstart, *limit, *namestart; 121 ssize_t numlen, namelen = 0; 122 char numbuf[12]; 123 char *numend; 124 125 if ((instr >= buffer && (buffer + buflen) > instr) || 126 (buffer >= instr && (instr + lenstr) > buffer)) 127 return (NSS_STR_PARSE_PARSE); 128 129 p = instr; 130 limit = p + lenstr; 131 132 while (p < limit && isspace(*p)) { 133 p++; 134 } 135 namestart = p; 136 while (p < limit && !isspace(*p)) { 137 p++; /* Skip over the canonical name */ 138 } 139 namelen = p - namestart; 140 141 if (buflen <= namelen) /* not enough buffer */ 142 return (NSS_STR_PARSE_ERANGE); 143 (void) memcpy(buffer, namestart, namelen); 144 buffer[namelen] = '\0'; 145 rpc->r_name = buffer; 146 147 while (p < limit && isspace(*p)) { 148 p++; 149 } 150 if (p >= limit) /* Syntax error -- no RPC number */ 151 return (NSS_STR_PARSE_PARSE); 152 numstart = p; 153 do { 154 p++; /* Find the end of the RPC number */ 155 } while (p < limit && !isspace(*p)); 156 numlen = p - numstart; 157 if (numlen >= sizeof (numbuf)) { 158 /* Syntax error -- supposed number is too long */ 159 return (NSS_STR_PARSE_PARSE); 160 } 161 (void) memcpy(numbuf, numstart, numlen); 162 numbuf[numlen] = '\0'; 163 rpc->r_number = (int)strtol(numbuf, &numend, 10); 164 if (*numend != '\0') 165 return (NSS_STR_PARSE_PARSE); 166 167 while (p < limit && isspace(*p)) { 168 p++; 169 } 170 /* 171 * Although nss_files_XY_all calls us with # stripped, 172 * we should be able to deal with it here in order to 173 * be more useful. 174 */ 175 if (p >= limit || *p == '#') { /* no aliases, no problem */ 176 char **ptr; 177 178 ptr = (char **)ROUND_UP(buffer + namelen + 1, 179 sizeof (char *)); 180 if ((char *)ptr >= buffer + buflen) { 181 rpc->r_aliases = 0; /* hope they don't try to peek in */ 182 return (NSS_STR_PARSE_ERANGE); 183 } 184 *ptr = 0; 185 rpc->r_aliases = ptr; 186 return (NSS_STR_PARSE_SUCCESS); 187 } 188 rpc->r_aliases = _nss_netdb_aliases(p, (int)(lenstr - (p - instr)), 189 buffer + namelen + 1, (int)(buflen - namelen - 1)); 190 return (NSS_STR_PARSE_SUCCESS); 191 } 192