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