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