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)(uintptr_t)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)(uintptr_t)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; 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)(uintptr_t)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 buf = NULL; 426 rpc = va_arg(ap, struct rpcent *); 427 buffer = va_arg(ap, char *); 428 bufsize = va_arg(ap, size_t); 429 errnop = va_arg(ap, int *); 430 431 *errnop = nis_getstate(&st); 432 if (*errnop != 0) 433 return (NS_UNAVAIL); 434 435 if (st->domain[0] == '\0') { 436 if (getdomainname(st->domain, sizeof(st->domain)) != 0) { 437 *errnop = errno; 438 return (NS_UNAVAIL); 439 } 440 } 441 442 no_name_active = 0; 443 do { 444 switch (how) 445 { 446 case nss_lt_name: 447 if (!st->no_name_map) 448 { 449 free(buf); 450 asprintf(&buf, "%s", name); 451 if (buf == NULL) 452 return (NS_TRYAGAIN); 453 rv = yp_match(st->domain, "rpc.byname", buf, 454 strlen(buf), &resultbuf, &resultbuflen); 455 456 switch (rv) { 457 case 0: 458 break; 459 case YPERR_MAP: 460 st->stepping = 0; 461 no_name_active = 1; 462 how = nss_lt_all; 463 464 rv = NS_NOTFOUND; 465 continue; 466 default: 467 rv = NS_NOTFOUND; 468 goto fin; 469 } 470 } else { 471 st->stepping = 0; 472 no_name_active = 1; 473 how = nss_lt_all; 474 475 rv = NS_NOTFOUND; 476 continue; 477 } 478 break; 479 case nss_lt_id: 480 free(buf); 481 asprintf(&buf, "%d", number); 482 if (buf == NULL) 483 return (NS_TRYAGAIN); 484 if (yp_match(st->domain, "rpc.bynumber", buf, 485 strlen(buf), &resultbuf, &resultbuflen)) { 486 rv = NS_NOTFOUND; 487 goto fin; 488 } 489 break; 490 case nss_lt_all: 491 if (!st->stepping) { 492 rv = yp_first(st->domain, "rpc.bynumber", 493 &st->current, 494 &st->currentlen, &resultbuf, 495 &resultbuflen); 496 if (rv) { 497 rv = NS_NOTFOUND; 498 goto fin; 499 } 500 st->stepping = 1; 501 } else { 502 lastkey = st->current; 503 rv = yp_next(st->domain, "rpc.bynumber", 504 st->current, 505 st->currentlen, &st->current, 506 &st->currentlen, 507 &resultbuf, &resultbuflen); 508 free(lastkey); 509 if (rv) { 510 st->stepping = 0; 511 rv = NS_NOTFOUND; 512 goto fin; 513 } 514 } 515 break; 516 } 517 518 /* we need a room for additional \n symbol */ 519 if (bufsize <= resultbuflen + 1 + _ALIGNBYTES + 520 sizeof(char *)) { 521 *errnop = ERANGE; 522 rv = NS_RETURN; 523 free(resultbuf); 524 break; 525 } 526 527 aliases=(char **)_ALIGN(&buffer[resultbuflen+2]); 528 aliases_size = (buffer + bufsize - (char *)aliases) / 529 sizeof(char *); 530 if (aliases_size < 1) { 531 *errnop = ERANGE; 532 rv = NS_RETURN; 533 free(resultbuf); 534 break; 535 } 536 537 /* 538 * rpcent_unpack expects lines terminated with \n -- make it happy 539 */ 540 memcpy(buffer, resultbuf, resultbuflen); 541 buffer[resultbuflen] = '\n'; 542 buffer[resultbuflen+1] = '\0'; 543 free(resultbuf); 544 545 if (rpcent_unpack(buffer, rpc, aliases, aliases_size, 546 errnop) != 0) { 547 if (*errnop == 0) 548 rv = NS_NOTFOUND; 549 else 550 rv = NS_RETURN; 551 } else { 552 if ((how == nss_lt_all) && (no_name_active != 0)) { 553 if (strcmp(rpc->r_name, name) == 0) 554 goto done; 555 for (rp = rpc->r_aliases; *rp != NULL; rp++) { 556 if (strcmp(*rp, name) == 0) 557 goto done; 558 } 559 rv = NS_NOTFOUND; 560 continue; 561 done: 562 rv = NS_SUCCESS; 563 } else 564 rv = NS_SUCCESS; 565 } 566 567 } while (!(rv & NS_TERMINATE) && (how == nss_lt_all)); 568 569 fin: 570 free(buf); 571 if ((rv == NS_SUCCESS) && (retval != NULL)) 572 *((struct rpcent **)retval) = rpc; 573 574 return (rv); 575 } 576 577 static int 578 nis_setrpcent(void *retval, void *mdata, va_list ap) 579 { 580 struct nis_state *st; 581 int rv; 582 583 rv = nis_getstate(&st); 584 if (rv != 0) 585 return (NS_UNAVAIL); 586 587 switch ((enum constants)(uintptr_t)mdata) 588 { 589 case SETRPCENT: 590 case ENDRPCENT: 591 free(st->current); 592 st->current = NULL; 593 st->stepping = 0; 594 break; 595 default: 596 break; 597 } 598 599 return (NS_UNAVAIL); 600 } 601 #endif 602 603 #ifdef NS_CACHING 604 static int 605 rpc_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) 606 { 607 char *name; 608 int rpc; 609 610 size_t desired_size, size; 611 enum nss_lookup_type lookup_type; 612 int res = NS_UNAVAIL; 613 614 lookup_type = (enum nss_lookup_type)(uintptr_t)cache_mdata; 615 switch (lookup_type) { 616 case nss_lt_name: 617 name = va_arg(ap, char *); 618 619 size = strlen(name); 620 desired_size = sizeof(enum nss_lookup_type) + size + 1; 621 if (desired_size > *buffer_size) { 622 res = NS_RETURN; 623 goto fin; 624 } 625 626 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 627 memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1); 628 629 res = NS_SUCCESS; 630 break; 631 case nss_lt_id: 632 rpc = va_arg(ap, int); 633 634 desired_size = sizeof(enum nss_lookup_type) + sizeof(int); 635 if (desired_size > *buffer_size) { 636 res = NS_RETURN; 637 goto fin; 638 } 639 640 memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type)); 641 memcpy(buffer + sizeof(enum nss_lookup_type), &rpc, 642 sizeof(int)); 643 644 res = NS_SUCCESS; 645 break; 646 default: 647 /* should be unreachable */ 648 return (NS_UNAVAIL); 649 } 650 651 fin: 652 *buffer_size = desired_size; 653 return (res); 654 } 655 656 static int 657 rpc_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, 658 void *cache_mdata) 659 { 660 char *name __unused; 661 int num __unused; 662 struct rpcent *rpc; 663 char *orig_buf __unused; 664 size_t orig_buf_size __unused; 665 666 struct rpcent new_rpc; 667 size_t desired_size, size, aliases_size; 668 char *p; 669 char **alias; 670 671 switch ((enum nss_lookup_type)(uintptr_t)cache_mdata) { 672 case nss_lt_name: 673 name = va_arg(ap, char *); 674 break; 675 case nss_lt_id: 676 num = va_arg(ap, int); 677 break; 678 case nss_lt_all: 679 break; 680 default: 681 /* should be unreachable */ 682 return (NS_UNAVAIL); 683 } 684 685 rpc = va_arg(ap, struct rpcent *); 686 orig_buf = va_arg(ap, char *); 687 orig_buf_size = va_arg(ap, size_t); 688 689 desired_size = _ALIGNBYTES + sizeof(struct rpcent) + sizeof(char *); 690 if (rpc->r_name != NULL) 691 desired_size += strlen(rpc->r_name) + 1; 692 693 if (rpc->r_aliases != NULL) { 694 aliases_size = 0; 695 for (alias = rpc->r_aliases; *alias; ++alias) { 696 desired_size += strlen(*alias) + 1; 697 ++aliases_size; 698 } 699 700 desired_size += _ALIGNBYTES + (aliases_size + 1) * 701 sizeof(char *); 702 } 703 704 if (*buffer_size < desired_size) { 705 /* this assignment is here for future use */ 706 *buffer_size = desired_size; 707 return (NS_RETURN); 708 } 709 710 new_rpc = *rpc; 711 712 *buffer_size = desired_size; 713 memset(buffer, 0, desired_size); 714 p = buffer + sizeof(struct rpcent) + sizeof(char *); 715 memcpy(buffer + sizeof(struct rpcent), &p, sizeof(char *)); 716 p = (char *)_ALIGN(p); 717 718 if (new_rpc.r_name != NULL) { 719 size = strlen(new_rpc.r_name); 720 memcpy(p, new_rpc.r_name, size); 721 new_rpc.r_name = p; 722 p += size + 1; 723 } 724 725 if (new_rpc.r_aliases != NULL) { 726 p = (char *)_ALIGN(p); 727 memcpy(p, new_rpc.r_aliases, sizeof(char *) * aliases_size); 728 new_rpc.r_aliases = (char **)p; 729 p += sizeof(char *) * (aliases_size + 1); 730 731 for (alias = new_rpc.r_aliases; *alias; ++alias) { 732 size = strlen(*alias); 733 memcpy(p, *alias, size); 734 *alias = p; 735 p += size + 1; 736 } 737 } 738 739 memcpy(buffer, &new_rpc, sizeof(struct rpcent)); 740 return (NS_SUCCESS); 741 } 742 743 static int 744 rpc_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, 745 void *cache_mdata) 746 { 747 char *name __unused; 748 int num __unused; 749 struct rpcent *rpc; 750 char *orig_buf; 751 size_t orig_buf_size; 752 int *ret_errno; 753 754 char *p; 755 char **alias; 756 757 switch ((enum nss_lookup_type)(uintptr_t)cache_mdata) { 758 case nss_lt_name: 759 name = va_arg(ap, char *); 760 break; 761 case nss_lt_id: 762 num = va_arg(ap, int); 763 break; 764 case nss_lt_all: 765 break; 766 default: 767 /* should be unreachable */ 768 return (NS_UNAVAIL); 769 } 770 771 rpc = va_arg(ap, struct rpcent *); 772 orig_buf = va_arg(ap, char *); 773 orig_buf_size = va_arg(ap, size_t); 774 ret_errno = va_arg(ap, int *); 775 776 if (orig_buf_size < 777 buffer_size - sizeof(struct rpcent) - sizeof(char *)) { 778 *ret_errno = ERANGE; 779 return (NS_RETURN); 780 } 781 782 memcpy(rpc, buffer, sizeof(struct rpcent)); 783 memcpy(&p, buffer + sizeof(struct rpcent), sizeof(char *)); 784 785 orig_buf = (char *)_ALIGN(orig_buf); 786 memcpy(orig_buf, buffer + sizeof(struct rpcent) + sizeof(char *) + 787 _ALIGN(p) - (size_t)p, 788 buffer_size - sizeof(struct rpcent) - sizeof(char *) - 789 _ALIGN(p) + (size_t)p); 790 p = (char *)_ALIGN(p); 791 792 NS_APPLY_OFFSET(rpc->r_name, orig_buf, p, char *); 793 if (rpc->r_aliases != NULL) { 794 NS_APPLY_OFFSET(rpc->r_aliases, orig_buf, p, char **); 795 796 for (alias = rpc->r_aliases ; *alias; ++alias) 797 NS_APPLY_OFFSET(*alias, orig_buf, p, char *); 798 } 799 800 if (retval != NULL) 801 *((struct rpcent **)retval) = rpc; 802 803 return (NS_SUCCESS); 804 } 805 806 NSS_MP_CACHE_HANDLING(rpc); 807 #endif /* NS_CACHING */ 808 809 810 /* get**_r functions implementation */ 811 static int 812 getrpcbyname_r(const char *name, struct rpcent *rpc, char *buffer, 813 size_t bufsize, struct rpcent **result) 814 { 815 #ifdef NS_CACHING 816 static const nss_cache_info cache_info = 817 NS_COMMON_CACHE_INFO_INITIALIZER( 818 rpc, (void *)nss_lt_name, 819 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); 820 #endif 821 static const ns_dtab dtab[] = { 822 { NSSRC_FILES, files_rpcent, (void *)nss_lt_name }, 823 #ifdef YP 824 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_name }, 825 #endif 826 #ifdef NS_CACHING 827 NS_CACHE_CB(&cache_info) 828 #endif 829 { NULL, NULL, NULL } 830 }; 831 int rv, ret_errno; 832 833 ret_errno = 0; 834 *result = NULL; 835 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbyname_r", defaultsrc, 836 name, rpc, buffer, bufsize, &ret_errno); 837 838 if (rv == NS_SUCCESS) 839 return (0); 840 else 841 return (ret_errno); 842 } 843 844 static int 845 getrpcbynumber_r(int number, struct rpcent *rpc, char *buffer, 846 size_t bufsize, struct rpcent **result) 847 { 848 #ifdef NS_CACHING 849 static const nss_cache_info cache_info = 850 NS_COMMON_CACHE_INFO_INITIALIZER( 851 rpc, (void *)nss_lt_id, 852 rpc_id_func, rpc_marshal_func, rpc_unmarshal_func); 853 #endif 854 static const ns_dtab dtab[] = { 855 { NSSRC_FILES, files_rpcent, (void *)nss_lt_id }, 856 #ifdef YP 857 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_id }, 858 #endif 859 #ifdef NS_CACHING 860 NS_CACHE_CB(&cache_info) 861 #endif 862 { NULL, NULL, NULL } 863 }; 864 int rv, ret_errno; 865 866 ret_errno = 0; 867 *result = NULL; 868 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcbynumber_r", defaultsrc, 869 number, rpc, buffer, bufsize, &ret_errno); 870 871 if (rv == NS_SUCCESS) 872 return (0); 873 else 874 return (ret_errno); 875 } 876 877 static int 878 getrpcent_r(struct rpcent *rpc, char *buffer, size_t bufsize, 879 struct rpcent **result) 880 { 881 #ifdef NS_CACHING 882 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 883 rpc, (void *)nss_lt_all, 884 rpc_marshal_func, rpc_unmarshal_func); 885 #endif 886 static const ns_dtab dtab[] = { 887 { NSSRC_FILES, files_rpcent, (void *)nss_lt_all }, 888 #ifdef YP 889 { NSSRC_NIS, nis_rpcent, (void *)nss_lt_all }, 890 #endif 891 #ifdef NS_CACHING 892 NS_CACHE_CB(&cache_info) 893 #endif 894 { NULL, NULL, NULL } 895 }; 896 int rv, ret_errno; 897 898 ret_errno = 0; 899 *result = NULL; 900 rv = nsdispatch(result, dtab, NSDB_RPC, "getrpcent_r", defaultsrc, 901 rpc, buffer, bufsize, &ret_errno); 902 903 if (rv == NS_SUCCESS) 904 return (0); 905 else 906 return (ret_errno); 907 } 908 909 /* get** wrappers for get**_r functions implementation */ 910 static void 911 rpcent_endstate(void *p) 912 { 913 if (p == NULL) 914 return; 915 916 free(((struct rpcent_state *)p)->buffer); 917 free(p); 918 } 919 920 static int 921 wrap_getrpcbyname_r(union key key, struct rpcent *rpc, char *buffer, 922 size_t bufsize, struct rpcent **res) 923 { 924 return (getrpcbyname_r(key.name, rpc, buffer, bufsize, res)); 925 } 926 927 static int 928 wrap_getrpcbynumber_r(union key key, struct rpcent *rpc, char *buffer, 929 size_t bufsize, struct rpcent **res) 930 { 931 return (getrpcbynumber_r(key.number, rpc, buffer, bufsize, res)); 932 } 933 934 static int 935 wrap_getrpcent_r(union key key __unused, struct rpcent *rpc, char *buffer, 936 size_t bufsize, struct rpcent **res) 937 { 938 return (getrpcent_r(rpc, buffer, bufsize, res)); 939 } 940 941 static struct rpcent * 942 getrpc(int (*fn)(union key, struct rpcent *, char *, size_t, struct rpcent **), 943 union key key) 944 { 945 int rv; 946 struct rpcent *res; 947 struct rpcent_state * st; 948 949 rv=rpcent_getstate(&st); 950 if (rv != 0) { 951 errno = rv; 952 return NULL; 953 } 954 955 if (st->buffer == NULL) { 956 st->buffer = malloc(RPCENT_STORAGE_INITIAL); 957 if (st->buffer == NULL) 958 return (NULL); 959 st->bufsize = RPCENT_STORAGE_INITIAL; 960 } 961 do { 962 rv = fn(key, &st->rpc, st->buffer, st->bufsize, &res); 963 if (res == NULL && rv == ERANGE) { 964 free(st->buffer); 965 if ((st->bufsize << 1) > RPCENT_STORAGE_MAX) { 966 st->buffer = NULL; 967 errno = ERANGE; 968 return (NULL); 969 } 970 st->bufsize <<= 1; 971 st->buffer = malloc(st->bufsize); 972 if (st->buffer == NULL) 973 return (NULL); 974 } 975 } while (res == NULL && rv == ERANGE); 976 if (rv != 0) 977 errno = rv; 978 979 return (res); 980 } 981 982 struct rpcent * 983 getrpcbyname(const char *name) 984 { 985 union key key; 986 987 key.name = name; 988 989 return (getrpc(wrap_getrpcbyname_r, key)); 990 } 991 992 struct rpcent * 993 getrpcbynumber(int number) 994 { 995 union key key; 996 997 key.number = number; 998 999 return (getrpc(wrap_getrpcbynumber_r, key)); 1000 } 1001 1002 struct rpcent * 1003 getrpcent(void) 1004 { 1005 union key key; 1006 1007 key.number = 0; /* not used */ 1008 1009 return (getrpc(wrap_getrpcent_r, key)); 1010 } 1011 1012 void 1013 setrpcent(int stayopen) 1014 { 1015 #ifdef NS_CACHING 1016 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 1017 rpc, (void *)nss_lt_all, 1018 NULL, NULL); 1019 #endif 1020 1021 static const ns_dtab dtab[] = { 1022 { NSSRC_FILES, files_setrpcent, (void *)SETRPCENT }, 1023 #ifdef YP 1024 { NSSRC_NIS, nis_setrpcent, (void *)SETRPCENT }, 1025 #endif 1026 #ifdef NS_CACHING 1027 NS_CACHE_CB(&cache_info) 1028 #endif 1029 { NULL, NULL, NULL } 1030 }; 1031 1032 (void)nsdispatch(NULL, dtab, NSDB_RPC, "setrpcent", defaultsrc, 1033 stayopen); 1034 } 1035 1036 void 1037 endrpcent(void) 1038 { 1039 #ifdef NS_CACHING 1040 static const nss_cache_info cache_info = NS_MP_CACHE_INFO_INITIALIZER( 1041 rpc, (void *)nss_lt_all, 1042 NULL, NULL); 1043 #endif 1044 1045 static const ns_dtab dtab[] = { 1046 { NSSRC_FILES, files_setrpcent, (void *)ENDRPCENT }, 1047 #ifdef YP 1048 { NSSRC_NIS, nis_setrpcent, (void *)ENDRPCENT }, 1049 #endif 1050 #ifdef NS_CACHING 1051 NS_CACHE_CB(&cache_info) 1052 #endif 1053 { NULL, NULL, NULL } 1054 }; 1055 1056 (void)nsdispatch(NULL, dtab, NSDB_RPC, "endrpcent", defaultsrc); 1057 } 1058