1/* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */ 2 3/*- 4 * Copyright (c) 2009, Sun Microsystems, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * - Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * - Neither the name of Sun Microsystems, Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#if defined(LIBC_SCCS) && !defined(lint) 32static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro"; 33#endif 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD$"); 36 37/* 38 * Copyright (c) 1984 by Sun Microsystems, Inc. 39 */ 40 41#include <sys/param.h> 42#include <sys/socket.h> 43#include <arpa/inet.h> 44#include <assert.h> 45#include <errno.h> 46#include <nsswitch.h> 47#include <netinet/in.h> 48#include <stdio.h> 49#include <string.h> 50#include <stdarg.h> 51#include <stdlib.h> 52#include <rpc/rpc.h> 53#ifdef YP 54#include <rpcsvc/yp_prot.h> 55#include <rpcsvc/ypclnt.h> 56#endif 57#include <unistd.h> 58#include "namespace.h" 59#include "reentrant.h" 60#include "un-namespace.h" 61#include "libc_private.h" 62#include "nss_tls.h" 63#ifdef NS_CACHING 64#include "nscache.h" 65#endif 66 67#define RPCDB "/etc/rpc" 68 69/* nsswitch declarations */ 70enum constants 71{ 72 SETRPCENT = 1, 73 ENDRPCENT = 2, 74 RPCENT_STORAGE_INITIAL = 1 << 10, /* 1 KByte */ 75 RPCENT_STORAGE_MAX = 1 << 20, /* 1 MByte */ 76}; 77 78static const ns_src defaultsrc[] = { 79 { NSSRC_FILES, NS_SUCCESS }, 80#ifdef YP 81 { NSSRC_NIS, NS_SUCCESS }, 82#endif 83 { NULL, 0 } 84}; 85 86/* files backend declarations */ 87struct files_state { 88 FILE *fp; 89 int stayopen; 90}; 91 92static int files_rpcent(void *, void *, va_list); 93static int files_setrpcent(void *, void *, va_list); 94 95static void files_endstate(void *); 96NSS_TLS_HANDLING(files); 97 98/* nis backend declarations */ 99#ifdef YP 100struct nis_state { 101 char domain[MAXHOSTNAMELEN]; 102 char *current; 103 int currentlen; 104 int stepping; 105 int no_name_map; 106}; 107 108static int nis_rpcent(void *, void *, va_list); 109static int nis_setrpcent(void *, void *, va_list); 110 111static void nis_endstate(void *); 112NSS_TLS_HANDLING(nis); 113#endif 114 115/* get** wrappers for get**_r functions declarations */ 116struct rpcent_state { 117 struct rpcent rpc; 118 char *buffer; 119 size_t bufsize; 120}; 121static void rpcent_endstate(void *); 122NSS_TLS_HANDLING(rpcent); 123 124union key { 125 const char *name; 126 int number; 127}; 128 129static int wrap_getrpcbyname_r(union key, struct rpcent *, char *, 130 size_t, struct rpcent **); 131static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *, 132 size_t, struct rpcent **); 133static int wrap_getrpcent_r(union key, struct rpcent *, char *, 134 size_t, struct rpcent **); 135static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *, 136 size_t, struct rpcent **), union key); 137 138#ifdef NS_CACHING 139static int rpc_id_func(char *, size_t *, va_list, void *); 140static int rpc_marshal_func(char *, size_t *, void *, va_list, void *); 141static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *); 142#endif 143 144static int 145rpcent_unpack(char *p, struct rpcent *rpc, char **r_aliases, 146 size_t aliases_size, int *errnop) 147{ 148 char *cp, **q; 149 150 assert(p != NULL); 151 152 if (*p == '#') 153 return (-1); 154 cp = strpbrk(p, "#\n"); 155 if (cp == NULL) 156 return (-1); 157 *cp = '\0'; 158 cp = strpbrk(p, " \t"); 159 if (cp == NULL) 160 return (-1); 161 *cp++ = '\0'; 162 /* THIS STUFF IS INTERNET SPECIFIC */ 163 rpc->r_name = p; 164 while (*cp == ' ' || *cp == '\t') 165 cp++; 166 rpc->r_number = atoi(cp); 167 q = rpc->r_aliases = r_aliases; 168 cp = strpbrk(cp, " \t"); 169 if (cp != NULL) 170 *cp++ = '\0'; 171 while (cp && *cp) { 172 if (*cp == ' ' || *cp == '\t') { 173 cp++; 174 continue; 175 } 176 if (q < &(r_aliases[aliases_size - 1])) 177 *q++ = cp; 178 else { 179 *errnop = ERANGE; 180 return -1; 181 } 182 183 cp = strpbrk(cp, " \t"); 184 if (cp != NULL) 185 *cp++ = '\0'; 186 } 187 *q = NULL; 188 return 0; 189} 190 191/* files backend implementation */ 192static void 193files_endstate(void *p) 194{ 195 FILE * f; 196 197 if (p == NULL) 198 return; 199 200 f = ((struct files_state *)p)->fp; 201 if (f != NULL) 202 fclose(f); 203 204 free(p); 205} 206 207static int 208files_rpcent(void *retval, void *mdata, va_list ap) 209{ 210 char *name; 211 int number; 212 struct rpcent *rpc; 213 char *buffer; 214 size_t bufsize; 215 int *errnop; 216 217 char *line; 218 size_t linesize; 219 char **aliases; 220 int aliases_size; 221 char **rp; 222 223 struct files_state *st; 224 int rv; 225 int stayopen; 226 enum nss_lookup_type how; 227 228 how = (enum nss_lookup_type)mdata; 229 switch (how) 230 { 231 case nss_lt_name: 232 name = va_arg(ap, char *); 233 break; 234 case nss_lt_id: 235 number = va_arg(ap, int); 236 break; 237 case nss_lt_all: 238 break; 239 default: 240 return (NS_NOTFOUND); 241 } 242 243 rpc = va_arg(ap, struct rpcent *); 244 buffer = va_arg(ap, char *); 245 bufsize = va_arg(ap, size_t); 246 errnop = va_arg(ap, int *); 247 248 *errnop = files_getstate(&st); 249 if (*errnop != 0) 250 return (NS_UNAVAIL); 251 252 if (st->fp == NULL && (st->fp = fopen(RPCDB, "r")) == NULL) { 253 *errnop = errno; 254 return (NS_UNAVAIL); 255 } 256 257 if (how == nss_lt_all) 258 stayopen = 1; 259 else { 260 rewind(st->fp); 261 stayopen = st->stayopen; 262 } 263 264 do { 265 if ((line = fgetln(st->fp, &linesize)) == NULL) { 266 *errnop = errno; 267 rv = NS_RETURN; 268 break; 269 } 270 271 if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) { 272 *errnop = ERANGE; 273 rv = NS_RETURN; 274 break; 275 } 276 277 aliases = (char **)_ALIGN(&buffer[linesize+1]); 278 aliases_size = (buffer + bufsize - 279 (char *)aliases)/sizeof(char *); 280 if (aliases_size < 1) { 281 *errnop = ERANGE; 282 rv = NS_RETURN; 283 break; 284 } 285 286 memcpy(buffer, line, linesize); 287 buffer[linesize] = '\0'; 288 289 rv = rpcent_unpack(buffer, rpc, aliases, aliases_size, errnop); 290 if (rv != 0) { 291 if (*errnop == 0) { 292 rv = NS_NOTFOUND; 293 continue; 294 } 295 else { 296 rv = NS_RETURN; 297 break; 298 } 299 } 300 301 switch (how) 302 { 303 case nss_lt_name: 304 if (strcmp(rpc->r_name, name) == 0) 305 goto done; 306 for (rp = rpc->r_aliases; *rp != NULL; rp++) { 307 if (strcmp(*rp, name) == 0) 308 goto done; 309 } 310 rv = NS_NOTFOUND; 311 continue; 312done: 313 rv = NS_SUCCESS; 314 break; 315 case nss_lt_id: 316 rv = (rpc->r_number == number) ? NS_SUCCESS : 317 NS_NOTFOUND; 318 break; 319 case nss_lt_all: 320 rv = NS_SUCCESS; 321 break; 322 } 323 324 } while (!(rv & NS_TERMINATE)); 325 326 if (!stayopen && st->fp!=NULL) { 327 fclose(st->fp); 328 st->fp = NULL; 329 } 330 331 if ((rv == NS_SUCCESS) && (retval != NULL)) 332 *((struct rpcent **)retval) = rpc; 333 334 return (rv); 335} 336 337static int 338files_setrpcent(void *retval, void *mdata, va_list ap) 339{ 340 struct files_state *st; 341 int rv; 342 int f; 343 344 rv = files_getstate(&st); 345 if (rv != 0) 346 return (NS_UNAVAIL); 347 348 switch ((enum constants)mdata) 349 { 350 case SETRPCENT: 351 f = va_arg(ap,int); 352 if (st->fp == NULL) 353 st->fp = fopen(RPCDB, "r"); 354 else 355 rewind(st->fp); 356 st->stayopen |= f; 357 break; 358 case ENDRPCENT: 359 if (st->fp != NULL) { 360 fclose(st->fp); 361 st->fp = NULL; 362 } 363 st->stayopen = 0; 364 break; 365 default: 366 break; 367 } 368 369 return (NS_UNAVAIL); 370} 371 372/* nis backend implementation */ 373#ifdef YP 374static void 375nis_endstate(void *p) 376{ 377 if (p == NULL) 378 return; 379 380 free(((struct nis_state *)p)->current); 381 free(p); 382} 383 384static int 385nis_rpcent(void *retval, void *mdata, va_list ap) 386{ 387 char *name; 388 int number; 389 struct rpcent *rpc; 390 char *buffer; 391 size_t bufsize; 392 int *errnop; 393 394 char **rp; 395 char **aliases; 396 int aliases_size; 397 398 char *lastkey; 399 char *resultbuf; 400 int resultbuflen; 401 char buf[YPMAXRECORD + 2]; 402 403 struct nis_state *st; 404 int rv; 405 enum nss_lookup_type how; 406 int no_name_active; 407 408 how = (enum nss_lookup_type)mdata; 409 switch (how) 410 { 411 case nss_lt_name: 412 name = va_arg(ap, char *); 413 break; 414 case nss_lt_id: 415 number = va_arg(ap, int); 416 break; 417 case nss_lt_all: 418 break; 419 default: 420 return (NS_NOTFOUND); 421 } 422 423 rpc = va_arg(ap, struct rpcent *); 424 buffer = va_arg(ap, char *); 425 bufsize = va_arg(ap, size_t); 426 errnop = va_arg(ap, int *); 427 428 *errnop = nis_getstate(&st); 429 if (*errnop != 0) 430 return (NS_UNAVAIL); 431 432 if (st->domain[0] == '\0') { 433 if (getdomainname(st->domain, sizeof(st->domain)) != 0) { 434 *errnop = errno; 435 return (NS_UNAVAIL); 436 } 437 } 438 439 no_name_active = 0; 440 do { 441 switch (how) 442 { 443 case nss_lt_name: 444 if (!st->no_name_map) 445 { 446 snprintf(buf, sizeof buf, "%s", name); 447 rv = yp_match(st->domain, "rpc.byname", buf, 448 strlen(buf), &resultbuf, &resultbuflen); 449 450 switch (rv) { 451 case 0: 452 break; 453 case YPERR_MAP: 454 st->stepping = 0; 455 no_name_active = 1; 456 how = nss_lt_all; 457 458 rv = NS_NOTFOUND; 459 continue; 460 default: 461 rv = NS_NOTFOUND; 462 goto fin; 463 } 464 } else { 465 st->stepping = 0; 466 no_name_active = 1; 467 how = nss_lt_all; 468 469 rv = NS_NOTFOUND; 470 continue; 471 } 472 break; 473 case nss_lt_id: 474 snprintf(buf, sizeof buf, "%d", number); 475 if (yp_match(st->domain, "rpc.bynumber", buf, 476 strlen(buf), &resultbuf, &resultbuflen)) { 477 rv = NS_NOTFOUND; 478 goto fin; 479 } 480 break; 481 case nss_lt_all: 482 if (!st->stepping) { 483 rv = yp_first(st->domain, "rpc.bynumber", 484 &st->current, 485 &st->currentlen, &resultbuf, 486 &resultbuflen); 487 if (rv) { 488 rv = NS_NOTFOUND; 489 goto fin; 490 } 491 st->stepping = 1; 492 } else { 493 lastkey = st->current; 494 rv = yp_next(st->domain, "rpc.bynumber", 495 st->current, 496 st->currentlen, &st->current, 497 &st->currentlen, 498 &resultbuf, &resultbuflen); 499 free(lastkey); 500 if (rv) { 501 st->stepping = 0; 502 rv = NS_NOTFOUND; 503 goto fin; 504 } 505 } 506 break; 507 } 508 509 /* we need a room for additional \n symbol */ 510 if (bufsize <= resultbuflen + 1 + _ALIGNBYTES + 511 sizeof(char *)) { 512 *errnop = ERANGE; 513 rv = NS_RETURN; 514 free(resultbuf); 515 break; 516 } 517 518 aliases=(char **)_ALIGN(&buffer[resultbuflen+2]); 519 aliases_size = (buffer + bufsize - (char *)aliases) / 520 sizeof(char *); 521 if (aliases_size < 1) { 522 *errnop = ERANGE; 523 rv = NS_RETURN; 524 free(resultbuf); 525 break; 526 } 527 528 /* 529 * rpcent_unpack expects lines terminated with \n -- make it happy 530 */ 531 memcpy(buffer, resultbuf, resultbuflen); 532 buffer[resultbuflen] = '\n'; 533 buffer[resultbuflen+1] = '\0'; 534 free(resultbuf); 535 536 if (rpcent_unpack(buffer, rpc, aliases, aliases_size, 537 errnop) != 0) { 538 if (*errnop == 0) 539 rv = NS_NOTFOUND; 540 else 541 rv = NS_RETURN; 542 } else { 543 if ((how == nss_lt_all) && (no_name_active != 0)) { 544 if (strcmp(rpc->r_name, name) == 0) 545 goto done; 546 for (rp = rpc->r_aliases; *rp != NULL; rp++) { 547 if (strcmp(*rp, name) == 0) 548 goto done; 549 } 550 rv = NS_NOTFOUND; 551 continue; 552done: 553 rv = NS_SUCCESS; 554 } else 555 rv = NS_SUCCESS; 556 } 557 558 } while (!(rv & NS_TERMINATE) && (how == nss_lt_all)); 559 560fin: 561 if ((rv == NS_SUCCESS) && (retval != NULL)) 562 *((struct rpcent **)retval) = rpc; 563 564 return (rv); 565} 566 567static int 568nis_setrpcent(void *retval, void *mdata, va_list ap) 569{ 570 struct nis_state *st; 571 int rv; 572 573 rv = nis_getstate(&st); 574 if (rv != 0) 575 return (NS_UNAVAIL); 576 577 switch ((enum constants)mdata) 578 { 579 case SETRPCENT: 580 case ENDRPCENT: 581 free(st->current); 582 st->current = NULL; 583 st->stepping = 0; 584 break; 585 default: 586 break; 587 } 588 589 return (NS_UNAVAIL); 590} 591#endif 592 593#ifdef NS_CACHING 594static int 595rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) 596{ 597 char *name; 598 int rpc; 599 600 size_t desired_size, size; 601 enum nss_lookup_type lookup_type; 602 int res = NS_UNAVAIL; 603 604 lookup_type = (enum nss_lookup_type)cache_mdata; 605 switch (lookup_type) { 606 case nss_lt_name: 607 name = va_arg(ap, char *); 608 609 size = strlen(name); 610 desired_size = sizeof(enum nss_lookup_type) + size + 1; 611 if (desired_size > *buffer_size) { 612 res = NS_RETURN; 613 goto fin; 614 } 615 616 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 617 memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1); 618 619 res = NS_SUCCESS; 620 break; 621 case nss_lt_id: 622 rpc = va_arg(ap, int); 623 624 desired_size = sizeof(enum nss_lookup_type) + sizeof(int); 625 if (desired_size > *buffer_size) { 626 res = NS_RETURN; 627 goto fin; 628 } 629 630 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 631 memcpy(buffer + sizeof(enum nss_lookup_type), &rpc, 632 sizeof(int)); 633 634 res = NS_SUCCESS; 635 break; 636 default: 637 /* should be unreachable */ 638 return (NS_UNAVAIL); 639 } 640 641fin: 642 *buffer_size = desired_size; 643 return (res); 644} 645 646static int 647rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, 648 void *cache_mdata) 649{ 650 char *name; 651 int num; 652 struct rpcent *rpc; 653 char *orig_buf; 654 size_t orig_buf_size; 655 656 struct rpcent new_rpc; 657 size_t desired_size, size, aliases_size; 658 char *p; 659 char **alias; 660 661 switch ((enum nss_lookup_type)cache_mdata) { 662 case nss_lt_name: 663 name = va_arg(ap, char *); 664 break; 665 case nss_lt_id: 666 num = va_arg(ap, int); 667 break; 668 case nss_lt_all: 669 break; 670 default: 671 /* should be unreachable */ 672 return (NS_UNAVAIL); 673 } 674 675 rpc = va_arg(ap, struct rpcent *); 676 orig_buf = va_arg(ap, char *); 677 orig_buf_size = va_arg(ap, size_t); 678 679 desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *); 680 if (rpc->r_name != NULL) 681 desired_size += strlen(rpc->r_name) + 1; 682 683 if (rpc->r_aliases != NULL) { 684 aliases_size = 0; 685 for (alias = rpc->r_aliases; *alias; ++alias) { 686 desired_size += strlen(*alias) + 1; 687 ++aliases_size; 688 } 689 690 desired_size += _ALIGNBYTES + (aliases_size + 1) * 691 sizeof(char *); 692 } 693 694 if (*buffer_size < desired_size) { 695 /* this assignment is here for future use */ 696 *buffer_size = desired_size; 697 return (NS_RETURN); 698 } 699 700 new_rpc = *rpc; 701 702 *buffer_size = desired_size; 703 memset(buffer, 0, desired_size); 704 p = buffer + sizeof(struct rpcent) + sizeof(char *); 705 memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *)); 706 p = (char *)_ALIGN(p); 707 708 if (new_rpc.r_name != NULL) { 709 size = strlen(new_rpc.r_name); 710 memcpy(p, new_rpc.r_name, size); 711 new_rpc.r_name = p; 712 p += size + 1; 713 } 714 715 if (new_rpc.r_aliases != NULL) { 716 p = (char *)_ALIGN(p); 717 memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size); 718 new_rpc.r_aliases = (char **)p; 719 p += sizeof(char *) * (aliases_size + 1); 720 721 for (alias = new_rpc.r_aliases; *alias; ++alias) { 722 size = strlen(*alias); 723 memcpy(p, *alias, size); 724 *alias = p; 725 p += size + 1; 726 } 727 } 728 729 memcpy(buffer, &new_rpc, sizeof(struct rpcent)); 730 return (NS_SUCCESS); 731} 732 733static int 734rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, 735 void *cache_mdata) 736{ 737 char *name; 738 int num; 739 struct rpcent *rpc; 740 char *orig_buf; 741 size_t orig_buf_size; 742 int *ret_errno; 743 744 char *p; 745 char **alias; 746 747 switch ((enum nss_lookup_type)cache_mdata) { 748 case nss_lt_name: 749 name = va_arg(ap, char *); 750 break; 751 case nss_lt_id: 752 num = va_arg(ap, int); 753 break; 754 case nss_lt_all: 755 break; 756 default: 757 /* should be unreachable */ 758 return (NS_UNAVAIL); 759 } 760 761 rpc = va_arg(ap, struct rpcent *); 762 orig_buf = va_arg(ap, char *); 763 orig_buf_size = va_arg(ap, size_t); 764 ret_errno = va_arg(ap, int *); 765 766 if (orig_buf_size < 767 buffer_size - sizeof(struct rpcent) - sizeof(char *)) { 768 *ret_errno = ERANGE; 769 return (NS_RETURN); 770 } 771 772 memcpy(rpc, buffer, sizeof(struct rpcent)); 773 memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *)); 774 775 orig_buf = (char *)_ALIGN(orig_buf); 776 memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) + 777 _ALIGN(p) - (size_t)p, 778 buffer_size - sizeof(struct rpcent) - sizeof(char *) - 779 _ALIGN(p) + (size_t)p); 780 p = (char *)_ALIGN(p); 781 782 NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *); 783 if (rpc->r_aliases != NULL) { 784 NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **); 785 786 for (alias = rpc->r_aliases ; *alias; ++alias) 787 NS_APPLY_OFFSET(*alias, orig_buf, p, char *); 788 } 789 790 if (retval != NULL) 791 *((struct rpcent **)retval) = rpc; 792 793 return (NS_SUCCESS); 794} 795 796NSS_MP_CACHE_HANDLING(rpc); 797#endif /* NS_CACHING */ 798 799 800/* get**_r functions implementation */ 801static int 802getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer, 803 size_t bufsize, struct rpcent **result) 804{ 805#ifdef NS_CACHING 806 static const nss_cache_info cache_info = 807 NS_COMMON_CACHE_INFO_INITIALIZER( 808 rpc, (void *)nss_lt_name, 809 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); 810#endif 811 static const ns_dtab dtab[] = { 812 { NSSRC_FILES, files_rpcent, (void *)nss_lt_name }, 813#ifdef YP 814 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name }, 815#endif 816#ifdef NS_CACHING 817 NS_CACHE_CB(&cache_info) 818#endif 819 { NULL, NULL, NULL } 820 }; 821 int rv, ret_errno; 822 823 ret_errno = 0; 824 *result = NULL; 825 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc, 826 name, rpc, buffer, bufsize, &ret_errno); 827 828 if (rv == NS_SUCCESS) 829 return (0); 830 else 831 return (ret_errno); 832} 833 834static int 835getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer, 836 size_t bufsize, struct rpcent **result) 837{ 838#ifdef NS_CACHING 839 static const nss_cache_info cache_info = 840 NS_COMMON_CACHE_INFO_INITIALIZER( 841 rpc, (void *)nss_lt_id, 842 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); 843#endif 844 static const ns_dtab dtab[] = { 845 { NSSRC_FILES, files_rpcent, (void *)nss_lt_id }, 846#ifdef YP 847 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id }, 848#endif 849#ifdef NS_CACHING 850 NS_CACHE_CB(&cache_info) 851#endif 852 { NULL, NULL, NULL } 853 }; 854 int rv, ret_errno; 855 856 ret_errno = 0; 857 *result = NULL; 858 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc, 859 number, rpc, buffer, bufsize, &ret_errno); 860 861 if (rv == NS_SUCCESS) 862 return (0); 863 else 864 return (ret_errno); 865} 866 867static int 868getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize, 869 struct rpcent **result) 870{ 871#ifdef NS_CACHING 872 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 873 rpc, (void *)nss_lt_all, 874 rpc_marshal_func, rpc_unmarshal_func); 875#endif 876 static const ns_dtab dtab[] = { 877 { NSSRC_FILES, files_rpcent, (void *)nss_lt_all }, 878#ifdef YP 879 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all }, 880#endif 881#ifdef NS_CACHING 882 NS_CACHE_CB(&cache_info) 883#endif 884 { NULL, NULL, NULL } 885 }; 886 int rv, ret_errno; 887 888 ret_errno = 0; 889 *result = NULL; 890 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc, 891 rpc, buffer, bufsize, &ret_errno); 892 893 if (rv == NS_SUCCESS) 894 return (0); 895 else 896 return (ret_errno); 897} 898 899/* get** wrappers for get**_r functions implementation */ 900static void 901rpcent_endstate(void *p) 902{ 903 if (p == NULL) 904 return; 905 906 free(((struct rpcent_state *)p)->buffer); 907 free(p); 908} 909 910static int 911wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer, 912 size_t bufsize, struct rpcent **res) 913{ 914 return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res)); 915} 916 917static int 918wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer, 919 size_t bufsize, struct rpcent **res) 920{ 921 return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res)); 922} 923 924static int 925wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer, 926 size_t bufsize, struct rpcent **res) 927{ 928 return (getrpcent_r(rpc, buffer, bufsize, res)); 929} 930 931static struct rpcent * 932getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **), 933 union key key) 934{ 935 int rv; 936 struct rpcent *res; 937 struct rpcent_state * st; 938 939 rv=rpcent_getstate(&st); 940 if (rv != 0) { 941 errno = rv; 942 return NULL; 943 } 944 945 if (st->buffer == NULL) { 946 st->buffer = malloc(RPCENT_STORAGE_INITIAL); 947 if (st->buffer == NULL) 948 return (NULL); 949 st->bufsize = RPCENT_STORAGE_INITIAL; 950 } 951 do { 952 rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res); 953 if (res == NULL && rv == ERANGE) { 954 free(st->buffer); 955 if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) { 956 st->buffer = NULL; 957 errno = ERANGE; 958 return (NULL); 959 } 960 st->bufsize <<= 1; 961 st->buffer = malloc(st->bufsize); 962 if (st->buffer == NULL) 963 return (NULL); 964 } 965 } while (res == NULL && rv == ERANGE); 966 if (rv != 0) 967 errno = rv; 968 969 return (res); 970} 971 972struct rpcent * 973getrpcbyname(const char *name) 974{ 975 union key key; 976 977 key.name = name; 978 979 return (getrpc(wrap_getrpcbyname_r, key)); 980} 981 982struct rpcent * 983getrpcbynumber(int number) 984{ 985 union key key; 986 987 key.number = number; 988 989 return (getrpc(wrap_getrpcbynumber_r, key)); 990} 991 992struct rpcent * 993getrpcent(void) 994{ 995 union key key; 996 997 key.number = 0; /* not used */ 998 999 return (getrpc(wrap_getrpcent_r, key)); 1000} 1001 1002void 1003setrpcent(int stayopen) 1004{ 1005#ifdef NS_CACHING 1006 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 1007 rpc, (void *)nss_lt_all, 1008 NULL, NULL); 1009#endif 1010 1011 static const ns_dtab dtab[] = { 1012 { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT }, 1013#ifdef YP 1014 { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT }, 1015#endif 1016#ifdef NS_CACHING 1017 NS_CACHE_CB(&cache_info) 1018#endif 1019 { NULL, NULL, NULL } 1020 }; 1021 1022 (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc, 1023 stayopen); 1024} 1025 1026void 1027endrpcent(void) 1028{ 1029#ifdef NS_CACHING 1030 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 1031 rpc, (void *)nss_lt_all, 1032 NULL, NULL); 1033#endif 1034 1035 static const ns_dtab dtab[] = { 1036 { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT }, 1037#ifdef YP 1038 { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT }, 1039#endif 1040#ifdef NS_CACHING 1041 NS_CACHE_CB(&cache_info) 1042#endif 1043 { NULL, NULL, NULL } 1044 }; 1045 1046 (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc); 1047} 1048