1/* $NetBSD$ */ 2 3/* 4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (c) 1996,1999 by Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20#if defined(LIBC_SCCS) && !defined(lint) 21static const char rcsid[] = "Id: nis_pr.c,v 1.4 2005/04/27 04:56:33 sra Exp"; 22#endif 23 24/* Imports */ 25 26#include "port_before.h" 27 28#ifndef WANT_IRS_NIS 29static int __bind_irs_nis_unneeded; 30#else 31 32#include <sys/types.h> 33#include <netinet/in.h> 34#include <arpa/nameser.h> 35#include <resolv.h> 36#ifdef T_NULL 37#undef T_NULL /* Silence re-definition warning of T_NULL. */ 38#endif 39#include <rpc/rpc.h> 40#include <rpc/xdr.h> 41#include <rpcsvc/yp_prot.h> 42#include <rpcsvc/ypclnt.h> 43 44#include <stdio.h> 45#include <string.h> 46#include <netdb.h> 47#include <ctype.h> 48#include <stdlib.h> 49#include <errno.h> 50 51#include <isc/memcluster.h> 52#include <irs.h> 53 54#include "port_after.h" 55 56#include "irs_p.h" 57#include "nis_p.h" 58 59/* Definitions */ 60 61struct pvt { 62 int needrewind; 63 char * nis_domain; 64 char * curkey_data; 65 int curkey_len; 66 char * curval_data; 67 int curval_len; 68 struct protoent proto; 69 char * prbuf; 70}; 71 72enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 }; 73 74static /*const*/ char protocols_byname[] = "protocols.byname"; 75static /*const*/ char protocols_bynumber[] = "protocols.bynumber"; 76 77/* Forward */ 78 79static void pr_close(struct irs_pr *); 80static struct protoent * pr_byname(struct irs_pr *, const char *); 81static struct protoent * pr_bynumber(struct irs_pr *, int); 82static struct protoent * pr_next(struct irs_pr *); 83static void pr_rewind(struct irs_pr *); 84static void pr_minimize(struct irs_pr *); 85 86static struct protoent * makeprotoent(struct irs_pr *this); 87static void nisfree(struct pvt *, enum do_what); 88 89/* Public */ 90 91struct irs_pr * 92irs_nis_pr(struct irs_acc *this) { 93 struct irs_pr *pr; 94 struct pvt *pvt; 95 96 if (!(pr = memget(sizeof *pr))) { 97 errno = ENOMEM; 98 return (NULL); 99 } 100 memset(pr, 0x5e, sizeof *pr); 101 if (!(pvt = memget(sizeof *pvt))) { 102 memput(pr, sizeof *pr); 103 errno = ENOMEM; 104 return (NULL); 105 } 106 memset(pvt, 0, sizeof *pvt); 107 pvt->needrewind = 1; 108 pvt->nis_domain = ((struct nis_p *)this->private)->domain; 109 pr->private = pvt; 110 pr->byname = pr_byname; 111 pr->bynumber = pr_bynumber; 112 pr->next = pr_next; 113 pr->rewind = pr_rewind; 114 pr->close = pr_close; 115 pr->minimize = pr_minimize; 116 pr->res_get = NULL; 117 pr->res_set = NULL; 118 return (pr); 119} 120 121/* Methods. */ 122 123static void 124pr_close(struct irs_pr *this) { 125 struct pvt *pvt = (struct pvt *)this->private; 126 127 nisfree(pvt, do_all); 128 if (pvt->proto.p_aliases) 129 free(pvt->proto.p_aliases); 130 if (pvt->prbuf) 131 free(pvt->prbuf); 132 memput(pvt, sizeof *pvt); 133 memput(this, sizeof *this); 134} 135 136static struct protoent * 137pr_byname(struct irs_pr *this, const char *name) { 138 struct pvt *pvt = (struct pvt *)this->private; 139 int r; 140 char *tmp; 141 142 nisfree(pvt, do_val); 143 DE_CONST(name, tmp); 144 r = yp_match(pvt->nis_domain, protocols_byname, tmp, 145 strlen(tmp), &pvt->curval_data, &pvt->curval_len); 146 if (r != 0) { 147 errno = ENOENT; 148 return (NULL); 149 } 150 return (makeprotoent(this)); 151} 152 153static struct protoent * 154pr_bynumber(struct irs_pr *this, int num) { 155 struct pvt *pvt = (struct pvt *)this->private; 156 char tmp[sizeof "-4294967295"]; 157 int r; 158 159 nisfree(pvt, do_val); 160 (void) sprintf(tmp, "%d", num); 161 r = yp_match(pvt->nis_domain, protocols_bynumber, tmp, strlen(tmp), 162 &pvt->curval_data, &pvt->curval_len); 163 if (r != 0) { 164 errno = ENOENT; 165 return (NULL); 166 } 167 return (makeprotoent(this)); 168} 169 170static struct protoent * 171pr_next(struct irs_pr *this) { 172 struct pvt *pvt = (struct pvt *)this->private; 173 struct protoent *rval; 174 int r; 175 176 do { 177 if (pvt->needrewind) { 178 nisfree(pvt, do_all); 179 r = yp_first(pvt->nis_domain, protocols_bynumber, 180 &pvt->curkey_data, &pvt->curkey_len, 181 &pvt->curval_data, &pvt->curval_len); 182 pvt->needrewind = 0; 183 } else { 184 char *newkey_data; 185 int newkey_len; 186 187 nisfree(pvt, do_val); 188 r = yp_next(pvt->nis_domain, protocols_bynumber, 189 pvt->curkey_data, pvt->curkey_len, 190 &newkey_data, &newkey_len, 191 &pvt->curval_data, &pvt->curval_len); 192 nisfree(pvt, do_key); 193 pvt->curkey_data = newkey_data; 194 pvt->curkey_len = newkey_len; 195 } 196 if (r != 0) { 197 errno = ENOENT; 198 return (NULL); 199 } 200 rval = makeprotoent(this); 201 } while (rval == NULL); 202 return (rval); 203} 204 205static void 206pr_rewind(struct irs_pr *this) { 207 struct pvt *pvt = (struct pvt *)this->private; 208 209 pvt->needrewind = 1; 210} 211 212static void 213pr_minimize(struct irs_pr *this) { 214 UNUSED(this); 215 /* NOOP */ 216} 217 218/* Private */ 219 220static struct protoent * 221makeprotoent(struct irs_pr *this) { 222 struct pvt *pvt = (struct pvt *)this->private; 223 char *p, **t; 224 int n, m; 225 226 if (pvt->prbuf) 227 free(pvt->prbuf); 228 pvt->prbuf = pvt->curval_data; 229 pvt->curval_data = NULL; 230 231 for (p = pvt->prbuf; *p && *p != '#';) 232 p++; 233 while (p > pvt->prbuf && isspace((unsigned char)(p[-1]))) 234 p--; 235 *p = '\0'; 236 237 p = pvt->prbuf; 238 n = m = 0; 239 240 pvt->proto.p_name = p; 241 while (*p && !isspace((unsigned char)*p)) 242 p++; 243 if (!*p) 244 return (NULL); 245 *p++ = '\0'; 246 247 while (*p && isspace((unsigned char)*p)) 248 p++; 249 pvt->proto.p_proto = atoi(p); 250 while (*p && !isspace((unsigned char)*p)) 251 p++; 252 *p++ = '\0'; 253 254 while (*p) { 255 if ((n + 1) >= m || !pvt->proto.p_aliases) { 256 m += 10; 257 t = realloc(pvt->proto.p_aliases, 258 m * sizeof(char *)); 259 if (!t) { 260 errno = ENOMEM; 261 goto cleanup; 262 } 263 pvt->proto.p_aliases = t; 264 } 265 pvt->proto.p_aliases[n++] = p; 266 while (*p && !isspace((unsigned char)*p)) 267 p++; 268 if (*p) 269 *p++ = '\0'; 270 } 271 if (!pvt->proto.p_aliases) 272 pvt->proto.p_aliases = malloc(sizeof(char *)); 273 if (!pvt->proto.p_aliases) 274 goto cleanup; 275 pvt->proto.p_aliases[n] = NULL; 276 return (&pvt->proto); 277 278 cleanup: 279 if (pvt->proto.p_aliases) { 280 free(pvt->proto.p_aliases); 281 pvt->proto.p_aliases = NULL; 282 } 283 if (pvt->prbuf) { 284 free(pvt->prbuf); 285 pvt->prbuf = NULL; 286 } 287 return (NULL); 288} 289 290static void 291nisfree(struct pvt *pvt, enum do_what do_what) { 292 if ((do_what & do_key) && pvt->curkey_data) { 293 free(pvt->curkey_data); 294 pvt->curkey_data = NULL; 295 } 296 if ((do_what & do_val) && pvt->curval_data) { 297 free(pvt->curval_data); 298 pvt->curval_data = NULL; 299 } 300} 301 302#endif /*WANT_IRS_NIS*/ 303 304/*! \file */ 305