174462Salfred/* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */ 274462Salfred 3261057Smav/*- 4261057Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261057Smav * All rights reserved. 61901Swollman * 7261057Smav * Redistribution and use in source and binary forms, with or without 8261057Smav * modification, are permitted provided that the following conditions are met: 9261057Smav * - Redistributions of source code must retain the above copyright notice, 10261057Smav * this list of conditions and the following disclaimer. 11261057Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261057Smav * this list of conditions and the following disclaimer in the documentation 13261057Smav * and/or other materials provided with the distribution. 14261057Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261057Smav * contributors may be used to endorse or promote products derived 16261057Smav * from this software without specific prior written permission. 17261057Smav * 18261057Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261057Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261057Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261057Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261057Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261057Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261057Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261057Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261057Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261057Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261057Smav * POSSIBILITY OF SUCH DAMAGE. 291901Swollman */ 301901Swollman 311901Swollman#if defined(LIBC_SCCS) && !defined(lint) 3274462Salfredstatic char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro"; 331901Swollman#endif 3492990Sobrien#include <sys/cdefs.h> 3592990Sobrien__FBSDID("$FreeBSD$"); 361901Swollman 371901Swollman/* 381901Swollman * Copyright (c) 1984 by Sun Microsystems, Inc. 391901Swollman */ 401901Swollman 41158115Sume#include <sys/param.h> 4274462Salfred#include <sys/types.h> 43158115Sume#include <sys/socket.h> 4474462Salfred#include <arpa/inet.h> 4574462Salfred#include <assert.h> 46158115Sume#include <errno.h> 47158115Sume#include <nsswitch.h> 48158115Sume#include <netinet/in.h> 491901Swollman#include <stdio.h> 50158115Sume#include <string.h> 51158115Sume#include <stdarg.h> 5211666Sphk#include <stdlib.h> 531901Swollman#include <rpc/rpc.h> 541901Swollman#ifdef YP 551901Swollman#include <rpcsvc/yp_prot.h> 561901Swollman#include <rpcsvc/ypclnt.h> 571901Swollman#endif 58158115Sume#include <unistd.h> 59158115Sume#include "namespace.h" 60158115Sume#include "reentrant.h" 6174462Salfred#include "un-namespace.h" 62111618Snectar#include "libc_private.h" 63158115Sume#include "nss_tls.h" 64158115Sume#ifdef NS_CACHING 65158115Sume#include "nscache.h" 66158115Sume#endif 671901Swollman 68158115Sume#define RPCDB "/etc/rpc" 69158115Sume 70158115Sume/* nsswitch declarations */ 71158115Sumeenum constants 72158115Sume{ 73158115Sume SETRPCENT = 1, 74158115Sume ENDRPCENT = 2, 75158115Sume RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */ 76158115Sume RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */ 77158115Sume}; 78158115Sume 79158115Sumestatic const ns_src defaultsrc[] = { 80158115Sume { NSSRC_FILES, NS_SUCCESS }, 81158115Sume#ifdef YP 82158115Sume { NSSRC_NIS, NS_SUCCESS }, 83158115Sume#endif 84158115Sume { NULL, 0 } 85158115Sume}; 86158115Sume 87158115Sume/* files backend declarations */ 88158115Sumestruct files_state { 89158115Sume FILE *fp; 901901Swollman int stayopen; 91158115Sume}; 92158115Sume 93158115Sumestatic int files_rpcent(void *, void *, va_list); 94158115Sumestatic int files_setrpcent(void *, void *, va_list); 95158115Sume 96158115Sumestatic void files_endstate(void *); 97158115SumeNSS_TLS_HANDLING(files); 98158115Sume 99158115Sume/* nis backend declarations */ 100158115Sume#ifdef YP 101158115Sumestruct nis_state { 102158115Sume char domain[MAXHOSTNAMELEN]; 1031901Swollman char *current; 1041901Swollman int currentlen; 105158115Sume int stepping; 106158115Sume int no_name_map; 107158115Sume}; 108158115Sume 109158115Sumestatic int nis_rpcent(void *, void *, va_list); 110158115Sumestatic int nis_setrpcent(void *, void *, va_list); 111158115Sume 112158115Sumestatic void nis_endstate(void *); 113158115SumeNSS_TLS_HANDLING(nis); 1141901Swollman#endif 1151901Swollman 116158115Sume/* get** wrappers for get**_r functions declarations */ 117158115Sumestruct rpcent_state { 118158115Sume struct rpcent rpc; 119158115Sume char *buffer; 120158115Sume size_t bufsize; 121158115Sume}; 122158115Sumestatic void rpcent_endstate(void *); 123158115SumeNSS_TLS_HANDLING(rpcent); 12474462Salfred 125158115Sumeunion key { 126158115Sume const char *name; 127158115Sume int number; 128158115Sume}; 1291901Swollman 130158115Sumestatic int wrap_getrpcbyname_r(union key, struct rpcent *, char *, 131158115Sume size_t, struct rpcent **); 132158115Sumestatic int wrap_getrpcbynumber_r(union key, struct rpcent *, char *, 133158115Sume size_t, struct rpcent **); 134158115Sumestatic int wrap_getrpcent_r(union key, struct rpcent *, char *, 135158115Sume size_t, struct rpcent **); 136158115Sumestatic struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *, 137158115Sume size_t, struct rpcent **), union key); 1381901Swollman 139158115Sume#ifdef NS_CACHING 140158115Sumestatic int rpc_id_func(char *, size_t *, va_list, void *); 141158115Sumestatic int rpc_marshal_func(char *, size_t *, void *, va_list, void *); 142158115Sumestatic int rpc_unmarshal_func(char *, size_t, void *, va_list, void *); 143158115Sume#endif 1441901Swollman 145158115Sumestatic int 146158115Sumerpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases, 147158115Sume size_t aliases_size, int *errnop) 1481901Swollman{ 149158115Sume char *cp, **q; 1501901Swollman 151158115Sume assert(p != NULL); 152158115Sume 153158115Sume if (*p == '#') 154158115Sume return (-1); 155158115Sume cp = strpbrk(p, "#\n"); 156158115Sume if (cp == NULL) 157158115Sume return (-1); 158158115Sume *cp = '\0'; 159158115Sume cp = strpbrk(p, " \t"); 160158115Sume if (cp == NULL) 161158115Sume return (-1); 162158115Sume *cp++ = '\0'; 163158115Sume /* THIS STUFF IS INTERNET SPECIFIC */ 164158115Sume rpc->r_name = p; 165158115Sume while (*cp == ' ' || *cp == '\t') 166158115Sume cp++; 167158115Sume rpc->r_number = atoi(cp); 168158115Sume q = rpc->r_aliases = r_aliases; 169158115Sume cp = strpbrk(cp, " \t"); 170158115Sume if (cp != NULL) 171158115Sume *cp++ = '\0'; 172158115Sume while (cp && *cp) { 173158115Sume if (*cp == ' ' || *cp == '\t') { 174158115Sume cp++; 175158115Sume continue; 176158115Sume } 177158115Sume if (q < &(r_aliases[aliases_size - 1])) 178158115Sume *q++ = cp; 179158115Sume else { 180158115Sume *errnop = ERANGE; 181158115Sume return -1; 182158115Sume } 183158115Sume 184158115Sume cp = strpbrk(cp, " \t"); 185158115Sume if (cp != NULL) 186158115Sume *cp++ = '\0'; 1871901Swollman } 188158115Sume *q = NULL; 189158115Sume return 0; 1901901Swollman} 1911901Swollman 192158115Sume/* files backend implementation */ 193158115Sumestatic void 194158115Sumefiles_endstate(void *p) 195158115Sume{ 196158115Sume FILE * f; 197158115Sume 198158115Sume if (p == NULL) 199158115Sume return; 200158115Sume 201158115Sume f = ((struct files_state *)p)->fp; 202158115Sume if (f != NULL) 203158115Sume fclose(f); 204158115Sume 205158115Sume free(p); 206158115Sume} 207158115Sume 208158115Sumestatic int 209158115Sumefiles_rpcent(void *retval, void *mdata, va_list ap) 210158115Sume{ 211158115Sume char *name; 21274462Salfred int number; 213158115Sume struct rpcent *rpc; 214158115Sume char *buffer; 215158115Sume size_t bufsize; 216158115Sume int *errnop; 217158115Sume 218158115Sume char *line; 219158115Sume size_t linesize; 220158115Sume char **aliases; 221158115Sume int aliases_size; 222158115Sume char **rp; 223158115Sume 224158115Sume struct files_state *st; 225158115Sume int rv; 226158115Sume int stayopen; 227158115Sume enum nss_lookup_type how; 228158115Sume 229158115Sume how = (enum nss_lookup_type)mdata; 230158115Sume switch (how) 231158115Sume { 232158115Sume case nss_lt_name: 233158115Sume name = va_arg(ap, char *); 234158115Sume break; 235158115Sume case nss_lt_id: 236158115Sume number = va_arg(ap, int); 237158115Sume break; 238158115Sume case nss_lt_all: 239158115Sume break; 240158115Sume default: 241158115Sume return (NS_NOTFOUND); 242158115Sume } 243158115Sume 244158115Sume rpc = va_arg(ap, struct rpcent *); 245158115Sume buffer = va_arg(ap, char *); 246158115Sume bufsize = va_arg(ap, size_t); 247158115Sume errnop = va_arg(ap, int *); 248158115Sume 249158115Sume *errnop = files_getstate(&st); 250158115Sume if (*errnop != 0) 251158115Sume return (NS_UNAVAIL); 252158115Sume 253158115Sume if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) { 254158115Sume *errnop = errno; 255158115Sume return (NS_UNAVAIL); 256158115Sume } 257158115Sume 258158115Sume if (how == nss_lt_all) 259158115Sume stayopen = 1; 260158115Sume else { 261158115Sume rewind(st->fp); 262158115Sume stayopen = st->stayopen; 263158115Sume } 264158115Sume 265158115Sume do { 266158115Sume if ((line = fgetln(st->fp, &linesize)) == NULL) { 267158115Sume *errnop = errno; 268158115Sume rv = NS_RETURN; 269158115Sume break; 270158115Sume } 271158115Sume 272158115Sume if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) { 273158115Sume *errnop = ERANGE; 274158115Sume rv = NS_RETURN; 275158115Sume break; 276158115Sume } 277158115Sume 278158115Sume aliases = (char **)_ALIGN(&buffer[linesize+1]); 279158115Sume aliases_size = (buffer + bufsize - 280158115Sume (char *)aliases)/sizeof(char *); 281158115Sume if (aliases_size < 1) { 282158115Sume *errnop = ERANGE; 283158115Sume rv = NS_RETURN; 284158115Sume break; 285158115Sume } 286158115Sume 287158115Sume memcpy(buffer, line, linesize); 288158115Sume buffer[linesize] = '\0'; 289158115Sume 290158115Sume rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop); 291158115Sume if (rv != 0) { 292158115Sume if (*errnop == 0) { 293158115Sume rv = NS_NOTFOUND; 294158115Sume continue; 295158115Sume } 296158115Sume else { 297158115Sume rv = NS_RETURN; 298158115Sume break; 299158115Sume } 300158115Sume } 301158115Sume 302158115Sume switch (how) 303158115Sume { 304158115Sume case nss_lt_name: 305158115Sume if (strcmp(rpc->r_name, name) == 0) 306158115Sume goto done; 307158115Sume for (rp = rpc->r_aliases; *rp != NULL; rp++) { 308158115Sume if (strcmp(*rp, name) == 0) 309158115Sume goto done; 310158115Sume } 311158115Sume rv = NS_NOTFOUND; 312158115Sume continue; 313158115Sumedone: 314158115Sume rv = NS_SUCCESS; 315158115Sume break; 316158115Sume case nss_lt_id: 317158115Sume rv = (rpc->r_number == number) ? NS_SUCCESS : 318158115Sume NS_NOTFOUND; 319158115Sume break; 320158115Sume case nss_lt_all: 321158115Sume rv = NS_SUCCESS; 322158115Sume break; 323158115Sume } 324158115Sume 325158115Sume } while (!(rv & NS_TERMINATE)); 326158115Sume 327158115Sume if (!stayopen && st->fp!=NULL) { 328158115Sume fclose(st->fp); 329158115Sume st->fp = NULL; 330158115Sume } 331158115Sume 332158115Sume if ((rv == NS_SUCCESS) && (retval != NULL)) 333158115Sume *((struct rpcent **)retval) = rpc; 334158115Sume 335158115Sume return (rv); 336158115Sume} 337158115Sume 338158115Sumestatic int 339158115Sumefiles_setrpcent(void *retval, void *mdata, va_list ap) 3401901Swollman{ 341158115Sume struct files_state *st; 342158115Sume int rv; 343158115Sume int f; 3441901Swollman 345158115Sume rv = files_getstate(&st); 346158115Sume if (rv != 0) 347158115Sume return (NS_UNAVAIL); 34874462Salfred 349158115Sume switch ((enum constants)mdata) 350158115Sume { 351158115Sume case SETRPCENT: 352158115Sume f = va_arg(ap,int); 353158115Sume if (st->fp == NULL) 354158115Sume st->fp = fopen(RPCDB, "r"); 355158115Sume else 356158115Sume rewind(st->fp); 357158115Sume st->stayopen |= f; 358158115Sume break; 359158115Sume case ENDRPCENT: 360158115Sume if (st->fp != NULL) { 361158115Sume fclose(st->fp); 362158115Sume st->fp = NULL; 363158115Sume } 364158115Sume st->stayopen = 0; 365158115Sume break; 366158115Sume default: 367158115Sume break; 368158115Sume } 369158115Sume 370158115Sume return (NS_UNAVAIL); 371158115Sume} 372158115Sume 373158115Sume/* nis backend implementation */ 374158115Sume#ifdef YP 375158115Sumestatic void 376158115Sumenis_endstate(void *p) 377158115Sume{ 378158115Sume if (p == NULL) 379158115Sume return; 380158115Sume 381158115Sume free(((struct nis_state *)p)->current); 382158115Sume free(p); 383158115Sume} 384158115Sume 385158115Sumestatic int 386158115Sumenis_rpcent(void *retval, void *mdata, va_list ap) 387158115Sume{ 388158115Sume char *name; 389158115Sume int number; 390158115Sume struct rpcent *rpc; 391158115Sume char *buffer; 392158115Sume size_t bufsize; 393158115Sume int *errnop; 394158115Sume 395158115Sume char **rp; 396158115Sume char **aliases; 397158115Sume int aliases_size; 398158115Sume 399158115Sume char *lastkey; 400158115Sume char *resultbuf; 401158115Sume int resultbuflen; 402158115Sume char buf[YPMAXRECORD + 2]; 403158115Sume 404158115Sume struct nis_state *st; 405158115Sume int rv; 406158115Sume enum nss_lookup_type how; 407158115Sume int no_name_active; 408158115Sume 409158115Sume how = (enum nss_lookup_type)mdata; 410158115Sume switch (how) 411158115Sume { 412158115Sume case nss_lt_name: 413158115Sume name = va_arg(ap, char *); 414158115Sume break; 415158115Sume case nss_lt_id: 416158115Sume number = va_arg(ap, int); 417158115Sume break; 418158115Sume case nss_lt_all: 419158115Sume break; 420158115Sume default: 421158115Sume return (NS_NOTFOUND); 422158115Sume } 423158115Sume 424158115Sume rpc = va_arg(ap, struct rpcent *); 425158115Sume buffer = va_arg(ap, char *); 426158115Sume bufsize = va_arg(ap, size_t); 427158115Sume errnop = va_arg(ap, int *); 428158115Sume 429158115Sume *errnop = nis_getstate(&st); 430158115Sume if (*errnop != 0) 431158115Sume return (NS_UNAVAIL); 432158115Sume 433158115Sume if (st->domain[0] == '\0') { 434158115Sume if (getdomainname(st->domain, sizeof(st->domain)) != 0) { 435158115Sume *errnop = errno; 436158115Sume return (NS_UNAVAIL); 437158115Sume } 438158115Sume } 439158115Sume 440158115Sume no_name_active = 0; 441158115Sume do { 442158115Sume switch (how) 443158115Sume { 444158115Sume case nss_lt_name: 445158115Sume if (!st->no_name_map) 446158115Sume { 447158115Sume snprintf(buf, sizeof buf, "%s", name); 448158115Sume rv = yp_match(st->domain, "rpc.byname", buf, 449158115Sume strlen(buf), &resultbuf, &resultbuflen); 450158115Sume 451158115Sume switch (rv) { 452158115Sume case 0: 453158115Sume break; 454158115Sume case YPERR_MAP: 455158115Sume st->stepping = 0; 456158115Sume no_name_active = 1; 457158115Sume how = nss_lt_all; 458158115Sume 459158115Sume rv = NS_NOTFOUND; 460158115Sume continue; 461158115Sume default: 462158115Sume rv = NS_NOTFOUND; 463158115Sume goto fin; 464158115Sume } 465158115Sume } else { 466158115Sume st->stepping = 0; 467158115Sume no_name_active = 1; 468158115Sume how = nss_lt_all; 469158115Sume 470158115Sume rv = NS_NOTFOUND; 471158115Sume continue; 472158115Sume } 473158115Sume break; 474158115Sume case nss_lt_id: 475158115Sume snprintf(buf, sizeof buf, "%d", number); 476158115Sume if (yp_match(st->domain, "rpc.bynumber", buf, 477158115Sume strlen(buf), &resultbuf, &resultbuflen)) { 478158115Sume rv = NS_NOTFOUND; 479158115Sume goto fin; 480158115Sume } 4811901Swollman break; 482158115Sume case nss_lt_all: 483158115Sume if (!st->stepping) { 484158115Sume rv = yp_first(st->domain, "rpc.bynumber", 485158115Sume &st->current, 486158115Sume &st->currentlen, &resultbuf, 487158115Sume &resultbuflen); 488158115Sume if (rv) { 489158115Sume rv = NS_NOTFOUND; 490158115Sume goto fin; 491158115Sume } 492158115Sume st->stepping = 1; 493158115Sume } else { 494158115Sume lastkey = st->current; 495158115Sume rv = yp_next(st->domain, "rpc.bynumber", 496158115Sume st->current, 497158115Sume st->currentlen, &st->current, 498158115Sume &st->currentlen, 499158115Sume &resultbuf, &resultbuflen); 500158115Sume free(lastkey); 501158115Sume if (rv) { 502158115Sume st->stepping = 0; 503158115Sume rv = NS_NOTFOUND; 504158115Sume goto fin; 505158115Sume } 506158115Sume } 507158115Sume break; 508158115Sume } 509158115Sume 510158115Sume /* we need a room for additional \n symbol */ 511158115Sume if (bufsize <= resultbuflen + 1 + _ALIGNBYTES + 512158115Sume sizeof(char *)) { 513158115Sume *errnop = ERANGE; 514158115Sume rv = NS_RETURN; 515158115Sume break; 516158115Sume } 517158115Sume 518158115Sume aliases=(char **)_ALIGN(&buffer[resultbuflen+2]); 519158115Sume aliases_size = (buffer + bufsize - (char *)aliases) / 520158115Sume sizeof(char *); 521158115Sume if (aliases_size < 1) { 522158115Sume *errnop = ERANGE; 523158115Sume rv = NS_RETURN; 524158115Sume break; 525158115Sume } 526158115Sume 527158115Sume /* 528158115Sume * rpcent_unpack expects lines terminated with \n -- make it happy 529158115Sume */ 530158115Sume memcpy(buffer, resultbuf, resultbuflen); 531158115Sume buffer[resultbuflen] = '\n'; 532158115Sume buffer[resultbuflen+1] = '\0'; 533158115Sume free(resultbuf); 534158115Sume 535158115Sume if (rpcent_unpack(buffer, rpc, aliases, aliases_size, 536158115Sume errnop) != 0) { 537158115Sume if (*errnop == 0) 538158115Sume rv = NS_NOTFOUND; 539158115Sume else 540158115Sume rv = NS_RETURN; 541158115Sume } else { 542158115Sume if ((how == nss_lt_all) && (no_name_active != 0)) { 543158115Sume if (strcmp(rpc->r_name, name) == 0) 544158115Sume goto done; 545158115Sume for (rp = rpc->r_aliases; *rp != NULL; rp++) { 546158115Sume if (strcmp(*rp, name) == 0) 547158115Sume goto done; 548158115Sume } 549158115Sume rv = NS_NOTFOUND; 550158115Sume continue; 551158115Sumedone: 552158115Sume rv = NS_SUCCESS; 553158115Sume } else 554158115Sume rv = NS_SUCCESS; 555158115Sume } 556158115Sume 557158115Sume } while (!(rv & NS_TERMINATE) && (how == nss_lt_all)); 558158115Sume 559158115Sumefin: 560158115Sume if ((rv == NS_SUCCESS) && (retval != NULL)) 561158115Sume *((struct rpcent **)retval) = rpc; 562158115Sume 563158115Sume return (rv); 564158115Sume} 565158115Sume 566158115Sumestatic int 567158115Sumenis_setrpcent(void *retval, void *mdata, va_list ap) 568158115Sume{ 569158115Sume struct nis_state *st; 570158115Sume int rv; 571158115Sume 572158115Sume rv = nis_getstate(&st); 573158115Sume if (rv != 0) 574158115Sume return (NS_UNAVAIL); 575158115Sume 576158115Sume switch ((enum constants)mdata) 577158115Sume { 578158115Sume case SETRPCENT: 579158115Sume case ENDRPCENT: 580158115Sume free(st->current); 581158115Sume st->current = NULL; 582158115Sume st->stepping = 0; 583158115Sume break; 584158115Sume default: 585158115Sume break; 5861901Swollman } 587158115Sume 588158115Sume return (NS_UNAVAIL); 5891901Swollman} 590158115Sume#endif 5911901Swollman 592158115Sume#ifdef NS_CACHING 593158115Sumestatic int 594158115Sumerpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) 595158115Sume{ 5961901Swollman char *name; 597158115Sume int rpc; 598158115Sume 599158115Sume size_t desired_size, size; 600158115Sume enum nss_lookup_type lookup_type; 601158115Sume int res = NS_UNAVAIL; 602158115Sume 603158115Sume lookup_type = (enum nss_lookup_type)cache_mdata; 604158115Sume switch (lookup_type) { 605158115Sume case nss_lt_name: 606158115Sume name = va_arg(ap, char *); 607158115Sume 608158115Sume size = strlen(name); 609158115Sume desired_size = sizeof(enum nss_lookup_type) + size + 1; 610158115Sume if (desired_size > *buffer_size) { 611158115Sume res = NS_RETURN; 612158115Sume goto fin; 613158115Sume } 614158115Sume 615158115Sume memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 616158115Sume memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1); 617158115Sume 618158115Sume res = NS_SUCCESS; 619158115Sume break; 620158115Sume case nss_lt_id: 621158115Sume rpc = va_arg(ap, int); 622158115Sume 623158115Sume desired_size = sizeof(enum nss_lookup_type) + sizeof(int); 624158115Sume if (desired_size > *buffer_size) { 625158115Sume res = NS_RETURN; 626158115Sume goto fin; 627158115Sume } 628158115Sume 629158115Sume memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 630158115Sume memcpy(buffer + sizeof(enum nss_lookup_type), &rpc, 631158115Sume sizeof(int)); 632158115Sume 633158115Sume res = NS_SUCCESS; 634158115Sume break; 635158115Sume default: 636158115Sume /* should be unreachable */ 637158115Sume return (NS_UNAVAIL); 638158115Sume } 639158115Sume 640158115Sumefin: 641158115Sume *buffer_size = desired_size; 642158115Sume return (res); 643158115Sume} 644158115Sume 645158115Sumestatic int 646158115Sumerpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, 647158115Sume void *cache_mdata) 6481901Swollman{ 649158115Sume char *name; 650158115Sume int num; 651158115Sume struct rpcent *rpc; 652158115Sume char *orig_buf; 653158115Sume size_t orig_buf_size; 6541901Swollman 655158115Sume struct rpcent new_rpc; 656158115Sume size_t desired_size, size, aliases_size; 657158115Sume char *p; 658158115Sume char **alias; 65974462Salfred 660158115Sume switch ((enum nss_lookup_type)cache_mdata) { 661158115Sume case nss_lt_name: 662158115Sume name = va_arg(ap, char *); 663158115Sume break; 664158115Sume case nss_lt_id: 665158115Sume num = va_arg(ap, int); 666158115Sume break; 667158115Sume case nss_lt_all: 668158115Sume break; 669158115Sume default: 670158115Sume /* should be unreachable */ 671158115Sume return (NS_UNAVAIL); 672158115Sume } 673158115Sume 674158115Sume rpc = va_arg(ap, struct rpcent *); 675158115Sume orig_buf = va_arg(ap, char *); 676158115Sume orig_buf_size = va_arg(ap, size_t); 677158115Sume 678158115Sume desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *); 679158115Sume if (rpc->r_name != NULL) 680158115Sume desired_size += strlen(rpc->r_name) + 1; 681158115Sume 682158115Sume if (rpc->r_aliases != NULL) { 683158115Sume aliases_size = 0; 684158115Sume for (alias = rpc->r_aliases; *alias; ++alias) { 685158115Sume desired_size += strlen(*alias) + 1; 686158115Sume ++aliases_size; 6871901Swollman } 688158115Sume 689158115Sume desired_size += _ALIGNBYTES + (aliases_size + 1) * 690158115Sume sizeof(char *); 6911901Swollman } 692158115Sume 693158115Sume if (*buffer_size < desired_size) { 694158115Sume /* this assignment is here for future use */ 695158115Sume *buffer_size = desired_size; 696158115Sume return (NS_RETURN); 697158115Sume } 698158115Sume 699199787Swollman new_rpc = *rpc; 700158115Sume 701158115Sume *buffer_size = desired_size; 702158115Sume memset(buffer, 0, desired_size); 703158115Sume p = buffer + sizeof(struct rpcent) + sizeof(char *); 704158115Sume memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *)); 705158115Sume p = (char *)_ALIGN(p); 706158115Sume 707158115Sume if (new_rpc.r_name != NULL) { 708158115Sume size = strlen(new_rpc.r_name); 709158115Sume memcpy(p, new_rpc.r_name, size); 710158115Sume new_rpc.r_name = p; 711158115Sume p += size + 1; 712158115Sume } 713158115Sume 714158115Sume if (new_rpc.r_aliases != NULL) { 715158115Sume p = (char *)_ALIGN(p); 716158115Sume memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size); 717158115Sume new_rpc.r_aliases = (char **)p; 718158115Sume p += sizeof(char *) * (aliases_size + 1); 719158115Sume 720158115Sume for (alias = new_rpc.r_aliases; *alias; ++alias) { 721158115Sume size = strlen(*alias); 722158115Sume memcpy(p, *alias, size); 723158115Sume *alias = p; 724158115Sume p += size + 1; 725158115Sume } 726158115Sume } 727158115Sume 728158115Sume memcpy(buffer, &new_rpc, sizeof(struct rpcent)); 729158115Sume return (NS_SUCCESS); 7301901Swollman} 7311901Swollman 732158115Sumestatic int 733158115Sumerpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, 734158115Sume void *cache_mdata) 7351901Swollman{ 736158115Sume char *name; 737158115Sume int num; 738158115Sume struct rpcent *rpc; 739158115Sume char *orig_buf; 740158115Sume size_t orig_buf_size; 741158115Sume int *ret_errno; 7421901Swollman 743158115Sume char *p; 744158115Sume char **alias; 745158115Sume 746158115Sume switch ((enum nss_lookup_type)cache_mdata) { 747158115Sume case nss_lt_name: 748158115Sume name = va_arg(ap, char *); 749158115Sume break; 750158115Sume case nss_lt_id: 751158115Sume num = va_arg(ap, int); 752158115Sume break; 753158115Sume case nss_lt_all: 754158115Sume break; 755158115Sume default: 756158115Sume /* should be unreachable */ 757158115Sume return (NS_UNAVAIL); 758158115Sume } 759158115Sume 760158115Sume rpc = va_arg(ap, struct rpcent *); 761158115Sume orig_buf = va_arg(ap, char *); 762158115Sume orig_buf_size = va_arg(ap, size_t); 763158115Sume ret_errno = va_arg(ap, int *); 764158115Sume 765158115Sume if (orig_buf_size < 766158115Sume buffer_size - sizeof(struct rpcent) - sizeof(char *)) { 767158115Sume *ret_errno = ERANGE; 768158115Sume return (NS_RETURN); 769158115Sume } 770158115Sume 771158115Sume memcpy(rpc, buffer, sizeof(struct rpcent)); 772158115Sume memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *)); 773158115Sume 774158115Sume orig_buf = (char *)_ALIGN(orig_buf); 775158115Sume memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) + 776158115Sume _ALIGN(p) - (size_t)p, 777158115Sume buffer_size - sizeof(struct rpcent) - sizeof(char *) - 778158115Sume _ALIGN(p) + (size_t)p); 779158115Sume p = (char *)_ALIGN(p); 780158115Sume 781158115Sume NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *); 782158115Sume if (rpc->r_aliases != NULL) { 783158115Sume NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **); 784158115Sume 785158115Sume for (alias = rpc->r_aliases ; *alias; ++alias) 786158115Sume NS_APPLY_OFFSET(*alias, orig_buf, p, char *); 787158115Sume } 788158115Sume 789158115Sume if (retval != NULL) 790158115Sume *((struct rpcent **)retval) = rpc; 791158115Sume 792158115Sume return (NS_SUCCESS); 793158115Sume} 794158115Sume 795158115SumeNSS_MP_CACHE_HANDLING(rpc); 796158115Sume#endif /* NS_CACHING */ 797158115Sume 798158115Sume 799158115Sume/* get**_r functions implementation */ 800158115Sumestatic int 801158115Sumegetrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer, 802158115Sume size_t bufsize, struct rpcent **result) 803158115Sume{ 804158115Sume#ifdef NS_CACHING 805158115Sume static const nss_cache_info cache_info = 806158115Sume NS_COMMON_CACHE_INFO_INITIALIZER( 807158115Sume rpc, (void *)nss_lt_name, 808158115Sume rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); 809158115Sume#endif 810158115Sume static const ns_dtab dtab[] = { 811158115Sume { NSSRC_FILES, files_rpcent, (void *)nss_lt_name }, 812158115Sume#ifdef YP 813158115Sume { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name }, 814158115Sume#endif 815158115Sume#ifdef NS_CACHING 816158115Sume NS_CACHE_CB(&cache_info) 817158115Sume#endif 818158115Sume { NULL, NULL, NULL } 819158115Sume }; 820158115Sume int rv, ret_errno; 821158115Sume 822158115Sume ret_errno = 0; 823158115Sume *result = NULL; 824158115Sume rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc, 825158115Sume name, rpc, buffer, bufsize, &ret_errno); 826158115Sume 827158115Sume if (rv == NS_SUCCESS) 828158115Sume return (0); 8291901Swollman else 830158115Sume return (ret_errno); 8311901Swollman} 8321901Swollman 833158115Sumestatic int 834158115Sumegetrpcbynumber_r(int number, struct rpcent *rpc, char *buffer, 835158115Sume size_t bufsize, struct rpcent **result) 8361901Swollman{ 837158115Sume#ifdef NS_CACHING 838158115Sume static const nss_cache_info cache_info = 839158115Sume NS_COMMON_CACHE_INFO_INITIALIZER( 840158115Sume rpc, (void *)nss_lt_id, 841158115Sume rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); 842158115Sume#endif 843158115Sume static const ns_dtab dtab[] = { 844158115Sume { NSSRC_FILES, files_rpcent, (void *)nss_lt_id }, 845158115Sume#ifdef YP 846158115Sume { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id }, 847158115Sume#endif 848158115Sume#ifdef NS_CACHING 849158115Sume NS_CACHE_CB(&cache_info) 850158115Sume#endif 851158115Sume { NULL, NULL, NULL } 852158115Sume }; 853158115Sume int rv, ret_errno; 8541901Swollman 855158115Sume ret_errno = 0; 856158115Sume *result = NULL; 857158115Sume rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc, 858158115Sume number, rpc, buffer, bufsize, &ret_errno); 859158115Sume 860158115Sume if (rv == NS_SUCCESS) 861158115Sume return (0); 862158115Sume else 863158115Sume return (ret_errno); 864158115Sume} 865158115Sume 866158115Sumestatic int 867158115Sumegetrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize, 868158115Sume struct rpcent **result) 869158115Sume{ 870158115Sume#ifdef NS_CACHING 871158115Sume static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 872158115Sume rpc, (void *)nss_lt_all, 873158115Sume rpc_marshal_func, rpc_unmarshal_func); 874158115Sume#endif 875158115Sume static const ns_dtab dtab[] = { 876158115Sume { NSSRC_FILES, files_rpcent, (void *)nss_lt_all }, 877158115Sume#ifdef YP 878158115Sume { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all }, 879158115Sume#endif 880158115Sume#ifdef NS_CACHING 881158115Sume NS_CACHE_CB(&cache_info) 882158115Sume#endif 883158115Sume { NULL, NULL, NULL } 884158115Sume }; 885158115Sume int rv, ret_errno; 886158115Sume 887158115Sume ret_errno = 0; 888158115Sume *result = NULL; 889158115Sume rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc, 890158115Sume rpc, buffer, bufsize, &ret_errno); 891158115Sume 892158115Sume if (rv == NS_SUCCESS) 893158115Sume return (0); 894158115Sume else 895158115Sume return (ret_errno); 896158115Sume} 897158115Sume 898158115Sume/* get** wrappers for get**_r functions implementation */ 899158115Sumestatic void 900158115Sumerpcent_endstate(void *p) 901158115Sume{ 902158115Sume if (p == NULL) 9031901Swollman return; 904158115Sume 905158115Sume free(((struct rpcent_state *)p)->buffer); 906158115Sume free(p); 907158115Sume} 908158115Sume 909158115Sumestatic int 910158115Sumewrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer, 911158115Sume size_t bufsize, struct rpcent **res) 912158115Sume{ 913158115Sume return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res)); 914158115Sume} 915158115Sume 916158115Sumestatic int 917158115Sumewrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer, 918158115Sume size_t bufsize, struct rpcent **res) 919158115Sume{ 920158115Sume return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res)); 921158115Sume} 922158115Sume 923158115Sumestatic int 924158115Sumewrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer, 925158115Sume size_t bufsize, struct rpcent **res) 926158115Sume{ 927158115Sume return (getrpcent_r(rpc, buffer, bufsize, res)); 928158115Sume} 929158115Sume 930158115Sumestatic struct rpcent * 931158115Sumegetrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **), 932158115Sume union key key) 933158115Sume{ 934158115Sume int rv; 935158115Sume struct rpcent *res; 936158115Sume struct rpcent_state * st; 937158115Sume 938158115Sume rv=rpcent_getstate(&st); 939158115Sume if (rv != 0) { 940158115Sume errno = rv; 941158115Sume return NULL; 9421901Swollman } 943158115Sume 944158115Sume if (st->buffer == NULL) { 945158115Sume st->buffer = malloc(RPCENT_STORAGE_INITIAL); 946158115Sume if (st->buffer == NULL) 947158115Sume return (NULL); 948158115Sume st->bufsize = RPCENT_STORAGE_INITIAL; 949158115Sume } 950158115Sume do { 951158115Sume rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res); 952158115Sume if (res == NULL && rv == ERANGE) { 953158115Sume free(st->buffer); 954158115Sume if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) { 955158115Sume st->buffer = NULL; 956158115Sume errno = ERANGE; 957158115Sume return (NULL); 958158115Sume } 959158115Sume st->bufsize <<= 1; 960158115Sume st->buffer = malloc(st->bufsize); 961158115Sume if (st->buffer == NULL) 962158115Sume return (NULL); 963158115Sume } 964158115Sume } while (res == NULL && rv == ERANGE); 965158115Sume if (rv != 0) 966158115Sume errno = rv; 967158115Sume 968158115Sume return (res); 9691901Swollman} 9701901Swollman 9711901Swollmanstruct rpcent * 972158115Sumegetrpcbyname(char *name) 973158115Sume{ 974158115Sume union key key; 975158115Sume 976158115Sume key.name = name; 977158115Sume 978158115Sume return (getrpc(wrap_getrpcbyname_r, key)); 979158115Sume} 980158115Sume 981158115Sumestruct rpcent * 982158115Sumegetrpcbynumber(int number) 983158115Sume{ 984158115Sume union key key; 985158115Sume 986158115Sume key.number = number; 987158115Sume 988158115Sume return (getrpc(wrap_getrpcbynumber_r, key)); 989158115Sume} 990158115Sume 991158115Sumestruct rpcent * 9921901Swollmangetrpcent() 9931901Swollman{ 994158115Sume union key key; 995158115Sume 996158115Sume key.number = 0; /* not used */ 997158115Sume 998158115Sume return (getrpc(wrap_getrpcent_r, key)); 999158115Sume} 1000158115Sume 1001158115Sumevoid 1002158115Sumesetrpcent(int stayopen) 1003158115Sume{ 1004158115Sume#ifdef NS_CACHING 1005158115Sume static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 1006158115Sume rpc, (void *)nss_lt_all, 1007158115Sume NULL, NULL); 10081901Swollman#endif 10091901Swollman 1010158115Sume static const ns_dtab dtab[] = { 1011158115Sume { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT }, 1012158115Sume#ifdef YP 1013158115Sume { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT }, 1014158115Sume#endif 1015158115Sume#ifdef NS_CACHING 1016158115Sume NS_CACHE_CB(&cache_info) 1017158115Sume#endif 1018158115Sume { NULL, NULL, NULL } 1019158115Sume }; 1020158115Sume 1021158115Sume (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc, 1022158115Sume stayopen); 10231901Swollman} 10241901Swollman 1025158115Sumevoid 1026158115Sumeendrpcent() 10271901Swollman{ 1028158115Sume#ifdef NS_CACHING 1029158115Sume static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 1030158115Sume rpc, (void *)nss_lt_all, 1031158115Sume NULL, NULL); 1032158115Sume#endif 10331901Swollman 1034158115Sume static const ns_dtab dtab[] = { 1035158115Sume { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT }, 1036158115Sume#ifdef YP 1037158115Sume { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT }, 1038158115Sume#endif 1039158115Sume#ifdef NS_CACHING 1040158115Sume NS_CACHE_CB(&cache_info) 1041158115Sume#endif 1042158115Sume { NULL, NULL, NULL } 1043158115Sume }; 104474462Salfred 1045169645Sjon (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc); 10461901Swollman} 1047