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