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