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) 34 static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro"; 35 #endif 36 #include <sys/cdefs.h> 37 __FBSDID("$FreeBSD$"); 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 */ 72 enum 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 80 static 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 */ 89 struct files_state { 90 FILE *fp; 91 int stayopen; 92 }; 93 94 static int files_rpcent(void *, void *, va_list); 95 static int files_setrpcent(void *, void *, va_list); 96 97 static void files_endstate(void *); 98 NSS_TLS_HANDLING(files); 99 100 /* nis backend declarations */ 101 #ifdef YP 102 struct nis_state { 103 char domain[MAXHOSTNAMELEN]; 104 char *current; 105 int currentlen; 106 int stepping; 107 int no_name_map; 108 }; 109 110 static int nis_rpcent(void *, void *, va_list); 111 static int nis_setrpcent(void *, void *, va_list); 112 113 static void nis_endstate(void *); 114 NSS_TLS_HANDLING(nis); 115 #endif 116 117 /* get** wrappers for get**_r functions declarations */ 118 struct rpcent_state { 119 struct rpcent rpc; 120 char *buffer; 121 size_t bufsize; 122 }; 123 static void rpcent_endstate(void *); 124 NSS_TLS_HANDLING(rpcent); 125 126 union key { 127 const char *name; 128 int number; 129 }; 130 131 static int wrap_getrpcbyname_r(union key, struct rpcent *, char *, 132 size_t, struct rpcent **); 133 static int wrap_getrpcbynumber_r(union key, struct rpcent *, char *, 134 size_t, struct rpcent **); 135 static int wrap_getrpcent_r(union key, struct rpcent *, char *, 136 size_t, struct rpcent **); 137 static struct rpcent *getrpc(int (*fn)(union key, struct rpcent *, char *, 138 size_t, struct rpcent **), union key); 139 140 #ifdef NS_CACHING 141 static int rpc_id_func(char *, size_t *, va_list, void *); 142 static int rpc_marshal_func(char *, size_t *, void *, va_list, void *); 143 static int rpc_unmarshal_func(char *, size_t, void *, va_list, void *); 144 #endif 145 146 static int 147 rpcent_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 */ 194 static void 195 files_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 209 static int 210 files_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; 314 done: 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 339 static int 340 files_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 376 static void 377 nis_endstate(void *p) 378 { 379 if (p == NULL) 380 return; 381 382 free(((struct nis_state *)p)->current); 383 free(p); 384 } 385 386 static int 387 nis_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; 554 done: 555 rv = NS_SUCCESS; 556 } else 557 rv = NS_SUCCESS; 558 } 559 560 } while (!(rv & NS_TERMINATE) && (how == nss_lt_all)); 561 562 fin: 563 if ((rv == NS_SUCCESS) && (retval != NULL)) 564 *((struct rpcent **)retval) = rpc; 565 566 return (rv); 567 } 568 569 static int 570 nis_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 596 static int 597 rpc_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 643 fin: 644 *buffer_size = desired_size; 645 return (res); 646 } 647 648 static int 649 rpc_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 735 static int 736 rpc_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 798 NSS_MP_CACHE_HANDLING(rpc); 799 #endif /* NS_CACHING */ 800 801 802 /* get**_r functions implementation */ 803 static int 804 getrpcbyname_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 836 static int 837 getrpcbynumber_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 869 static int 870 getrpcent_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 */ 902 static void 903 rpcent_endstate(void *p) 904 { 905 if (p == NULL) 906 return; 907 908 free(((struct rpcent_state *)p)->buffer); 909 free(p); 910 } 911 912 static int 913 wrap_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 919 static int 920 wrap_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 926 static int 927 wrap_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 933 static struct rpcent * 934 getrpc(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 974 struct rpcent * 975 getrpcbyname(const char *name) 976 { 977 union key key; 978 979 key.name = name; 980 981 return (getrpc(wrap_getrpcbyname_r, key)); 982 } 983 984 struct rpcent * 985 getrpcbynumber(int number) 986 { 987 union key key; 988 989 key.number = number; 990 991 return (getrpc(wrap_getrpcbynumber_r, key)); 992 } 993 994 struct rpcent * 995 getrpcent(void) 996 { 997 union key key; 998 999 key.number = 0; /* not used */ 1000 1001 return (getrpc(wrap_getrpcent_r, key)); 1002 } 1003 1004 void 1005 setrpcent(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 1028 void 1029 endrpcent(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