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