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