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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* 29 * Rentrant (MT-safe) getrpcYY interfaces. 30 */ 31 32 #pragma ident "%Z%%M% %I% %E% SMI" 33 34 #include "mt.h" 35 #include <ctype.h> 36 #include <nss_dbdefs.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <rpc/rpcent.h> 40 41 extern int str2rpcent(const char *, int, void *, char *, int); 42 43 static int rpc_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 void 49 _nss_initf_rpc(nss_db_params_t *p) 50 { 51 p->name = NSS_DBNAM_RPC; 52 p->default_config = NSS_DEFCONF_RPC; 53 } 54 55 struct rpcent * 56 getrpcbyname_r(const char *name, struct rpcent *result, char *buffer, 57 int buflen) 58 { 59 nss_XbyY_args_t arg; 60 nss_status_t res; 61 62 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2rpcent); 63 arg.key.name = name; 64 arg.stayopen = rpc_stayopen; 65 res = nss_search(&db_root, _nss_initf_rpc, 66 NSS_DBOP_RPC_BYNAME, &arg); 67 arg.status = res; 68 return ((struct rpcent *)NSS_XbyY_FINI(&arg)); 69 } 70 71 struct rpcent * 72 getrpcbynumber_r(const int number, struct rpcent *result, char *buffer, 73 int buflen) 74 { 75 nss_XbyY_args_t arg; 76 nss_status_t res; 77 78 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2rpcent); 79 arg.key.number = number; 80 arg.stayopen = rpc_stayopen; 81 res = nss_search(&db_root, _nss_initf_rpc, 82 NSS_DBOP_RPC_BYNUMBER, &arg); 83 arg.status = res; 84 return ((struct rpcent *)NSS_XbyY_FINI(&arg)); 85 } 86 87 void 88 setrpcent(const int stay) 89 { 90 rpc_stayopen |= stay; 91 nss_setent(&db_root, _nss_initf_rpc, &context); 92 } 93 94 void 95 endrpcent(void) 96 { 97 rpc_stayopen = 0; 98 nss_endent(&db_root, _nss_initf_rpc, &context); 99 nss_delete(&db_root); 100 } 101 102 struct rpcent * 103 getrpcent_r(struct rpcent *result, char *buffer, int buflen) 104 { 105 nss_XbyY_args_t arg; 106 nss_status_t res; 107 108 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2rpcent); 109 /* No key, no stayopen */ 110 res = nss_getent(&db_root, _nss_initf_rpc, &context, &arg); 111 arg.status = res; 112 return ((struct rpcent *)NSS_XbyY_FINI(&arg)); 113 } 114 115 int 116 str2rpcent(const char *instr, int lenstr, void *ent, char *buffer, int buflen) 117 { 118 struct rpcent *rpc = (struct rpcent *)ent; 119 const char *p, *numstart, *limit, *namestart; 120 ssize_t numlen, namelen = 0; 121 char numbuf[12]; 122 char *numend; 123 124 if ((instr >= buffer && (buffer + buflen) > instr) || 125 (buffer >= instr && (instr + lenstr) > buffer)) 126 return (NSS_STR_PARSE_PARSE); 127 128 p = instr; 129 limit = p + lenstr; 130 131 while (p < limit && isspace(*p)) { 132 p++; 133 } 134 namestart = p; 135 while (p < limit && !isspace(*p)) { 136 p++; /* Skip over the canonical name */ 137 } 138 namelen = p - namestart; 139 140 if (buflen <= namelen) /* not enough buffer */ 141 return (NSS_STR_PARSE_ERANGE); 142 (void) memcpy(buffer, namestart, namelen); 143 buffer[namelen] = '\0'; 144 rpc->r_name = buffer; 145 146 while (p < limit && isspace(*p)) { 147 p++; 148 } 149 if (p >= limit) /* Syntax error -- no RPC number */ 150 return (NSS_STR_PARSE_PARSE); 151 numstart = p; 152 do { 153 p++; /* Find the end of the RPC number */ 154 } while (p < limit && !isspace(*p)); 155 numlen = p - numstart; 156 if (numlen >= sizeof (numbuf)) { 157 /* Syntax error -- supposed number is too long */ 158 return (NSS_STR_PARSE_PARSE); 159 } 160 (void) memcpy(numbuf, numstart, numlen); 161 numbuf[numlen] = '\0'; 162 rpc->r_number = (int)strtol(numbuf, &numend, 10); 163 if (*numend != '\0') 164 return (NSS_STR_PARSE_PARSE); 165 166 while (p < limit && isspace(*p)) { 167 p++; 168 } 169 /* 170 * Although nss_files_XY_all calls us with # stripped, 171 * we should be able to deal with it here in order to 172 * be more useful. 173 */ 174 if (p >= limit || *p == '#') { /* no aliases, no problem */ 175 char **ptr; 176 177 ptr = (char **)ROUND_UP(buffer + namelen + 1, 178 sizeof (char *)); 179 if ((char *)ptr >= buffer + buflen) { 180 rpc->r_aliases = 0; /* hope they don't try to peek in */ 181 return (NSS_STR_PARSE_ERANGE); 182 } 183 *ptr = 0; 184 rpc->r_aliases = ptr; 185 return (NSS_STR_PARSE_SUCCESS); 186 } 187 rpc->r_aliases = _nss_netdb_aliases(p, (int)(lenstr - (p - instr)), 188 buffer + namelen + 1, (int)(buflen - namelen - 1)); 189 return (NSS_STR_PARSE_SUCCESS); 190 } 191