Print this page
4729 __rpcb_findaddr_timed should try rpcbind protocol 4 first

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libnsl/rpc/rpcb_clnt.c
          +++ new/usr/src/lib/libnsl/rpc/rpcb_clnt.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * When distributing Covered Code, include this CDDL HEADER in each
  15   15   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16   * If applicable, add the following below this CDDL HEADER, with the
  17   17   * fields enclosed by brackets "[]" replaced with your own identifying
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
  22   22  
  23   23  /*
       24 + * Copyright 2014 Gary Mills
  24   25   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25   26   * Use is subject to license terms.
  26   27   */
  27   28  
  28   29  /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  29   30  /* All Rights Reserved */
  30   31  /*
  31   32   * Portions of this source code were derived from Berkeley
  32   33   * 4.3 BSD under license from the Regents of the University of
  33   34   * California.
  34   35   */
  35   36  
  36      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  37      -
  38   37  /*
  39   38   * interface to rpcbind rpc service.
  40   39   */
  41   40  
  42   41  #include "mt.h"
  43   42  #include "rpc_mt.h"
  44   43  #include <assert.h>
  45   44  #include <rpc/rpc.h>
  46   45  #include <rpc/rpcb_prot.h>
  47   46  #include <netconfig.h>
  48   47  #include <netdir.h>
  49   48  #include <rpc/nettype.h>
  50   49  #include <syslog.h>
  51   50  #ifdef PORTMAP
  52   51  #include <netinet/in.h>         /* FOR IPPROTO_TCP/UDP definitions */
  53   52  #include <rpc/pmap_prot.h>
  54   53  #endif
  55      -#ifdef ND_DEBUG
  56      -#include <stdio.h>
  57      -#endif
  58   54  #include <sys/utsname.h>
  59   55  #include <errno.h>
  60   56  #include <stdlib.h>
  61   57  #include <string.h>
  62   58  #include <unistd.h>
  63   59  
  64   60  static struct timeval tottimeout = { 60, 0 };
  65   61  static const struct timeval rmttimeout = { 3, 0 };
  66   62  static struct timeval rpcbrmttime = { 15, 0 };
  67   63  
↓ open down ↓ 94 lines elided ↑ open up ↑
 162  158  check_cache(char *host, char *netid)
 163  159  {
 164  160          struct address_cache *cptr;
 165  161  
 166  162          /* READ LOCK HELD ON ENTRY: rpcbaddr_cache_lock */
 167  163  
 168  164          assert(RW_READ_HELD(&rpcbaddr_cache_lock));
 169  165          for (cptr = front; cptr != NULL; cptr = cptr->ac_next) {
 170  166                  if ((strcmp(cptr->ac_host, host) == 0) &&
 171  167                      (strcmp(cptr->ac_netid, netid) == 0) &&
 172      -                        (time(NULL) <= cptr->ac_maxtime)) {
 173      -#ifdef ND_DEBUG
 174      -                        fprintf(stderr, "Found cache entry for %s: %s\n",
 175      -                                host, netid);
 176      -#endif
      168 +                    (time(NULL) <= cptr->ac_maxtime)) {
 177  169                          return (cptr);
 178  170                  }
 179  171          }
 180  172          return (NULL);
 181  173  }
 182  174  
 183  175  static void
 184  176  delete_cache(struct netbuf *addr)
 185  177  {
 186  178          struct address_cache *cptr, *prevptr = NULL;
↓ open down ↓ 28 lines elided ↑ open up ↑
 215  207          ad_cache = malloc(sizeof (struct address_cache));
 216  208          if (!ad_cache) {
 217  209                  goto memerr;
 218  210          }
 219  211          ad_cache->ac_maxtime = time(NULL) + CACHE_TTL;
 220  212          ad_cache->ac_host = strdup(host);
 221  213          ad_cache->ac_netid = strdup(netid);
 222  214          ad_cache->ac_uaddr = uaddr ? strdup(uaddr) : NULL;
 223  215          ad_cache->ac_taddr = malloc(sizeof (struct netbuf));
 224  216          if (!ad_cache->ac_host || !ad_cache->ac_netid || !ad_cache->ac_taddr ||
 225      -                (uaddr && !ad_cache->ac_uaddr)) {
      217 +            (uaddr && !ad_cache->ac_uaddr)) {
 226  218                  goto memerr1;
 227  219          }
 228  220  
 229  221          ad_cache->ac_taddr->len = ad_cache->ac_taddr->maxlen = taddr->len;
 230  222          ad_cache->ac_taddr->buf = malloc(taddr->len);
 231  223          if (ad_cache->ac_taddr->buf == NULL) {
 232  224                  goto memerr1;
 233  225          }
 234  226  
 235  227          (void) memcpy(ad_cache->ac_taddr->buf, taddr->buf, taddr->len);
 236      -#ifdef ND_DEBUG
 237      -        (void) fprintf(stderr, "Added to cache: %s : %s\n", host, netid);
 238      -#endif
 239  228  
 240  229  /* VARIABLES PROTECTED BY rpcbaddr_cache_lock:  cptr */
 241  230  
 242  231          (void) rw_wrlock(&rpcbaddr_cache_lock);
 243  232          if (cachesize < CACHESIZE) {
 244  233                  ad_cache->ac_next = front;
 245  234                  front = ad_cache;
 246  235                  cachesize++;
 247  236          } else {
 248  237                  /* Free the last entry */
 249  238                  cptr = front;
 250  239                  prevptr = NULL;
 251  240                  while (cptr->ac_next) {
 252  241                          prevptr = cptr;
 253  242                          cptr = cptr->ac_next;
 254  243                  }
 255  244  
 256      -#ifdef ND_DEBUG
 257      -                fprintf(stderr, "Deleted from cache: %s : %s\n",
 258      -                        cptr->ac_host, cptr->ac_netid);
 259      -#endif
 260  245                  free(cptr->ac_host);
 261  246                  free(cptr->ac_netid);
 262  247                  free(cptr->ac_taddr->buf);
 263  248                  free(cptr->ac_taddr);
 264  249                  if (cptr->ac_uaddr)
 265  250                          free(cptr->ac_uaddr);
 266  251  
 267  252                  if (prevptr) {
 268  253                          prevptr->ac_next = NULL;
 269  254                          ad_cache->ac_next = front;
↓ open down ↓ 52 lines elided ↑ open up ↑
 322  307  
 323  308  /* VARIABLES PROTECTED BY rpcbaddr_cache_lock:  ad_cache */
 324  309  
 325  310          /* Get the address of the rpcbind.  Check cache first */
 326  311          addr_to_delete.len = 0;
 327  312          (void) rw_rdlock(&rpcbaddr_cache_lock);
 328  313          ad_cache = check_cache(host, nconf->nc_netid);
 329  314          if (ad_cache != NULL) {
 330  315                  addr = ad_cache->ac_taddr;
 331  316                  client = _clnt_tli_create_timed(RPC_ANYFD, nconf, addr,
 332      -                                RPCBPROG, RPCBVERS4, 0, 0, tp);
      317 +                    RPCBPROG, RPCBVERS4, 0, 0, tp);
 333  318                  if (client != NULL) {
 334  319                          if (targaddr) {
 335  320                                  /*
 336  321                                   * case where a client handle is created
 337  322                                   * without a targaddr and the handle is
 338  323                                   * requested with a targaddr
 339  324                                   */
 340  325                                  if (ad_cache->ac_uaddr != NULL) {
 341  326                                          *targaddr = strdup(ad_cache->ac_uaddr);
 342  327                                          if (*targaddr == NULL) {
 343  328                                                  syslog(LOG_ERR,
 344  329                                                  "_getclnthandle_timed: strdup "
 345  330                                                  "failed.");
 346  331                                                  rpc_createerr.cf_stat =
 347      -                                                        RPC_SYSTEMERROR;
      332 +                                                    RPC_SYSTEMERROR;
 348  333                                                  (void) rw_unlock(
 349      -                                                        &rpcbaddr_cache_lock);
      334 +                                                    &rpcbaddr_cache_lock);
 350  335                                                  return (NULL);
 351  336                                          }
 352  337                                  } else {
 353  338                                          *targaddr = NULL;
 354  339                                  }
 355  340                          }
 356  341                          (void) rw_unlock(&rpcbaddr_cache_lock);
 357  342                          return (client);
 358  343                  }
 359  344                  if (rpc_createerr.cf_stat == RPC_SYSTEMERROR) {
↓ open down ↓ 14 lines elided ↑ open up ↑
 374  359                   * Assume this may be due to cache data being
 375  360                   *  outdated
 376  361                   */
 377  362                  (void) rw_wrlock(&rpcbaddr_cache_lock);
 378  363                  delete_cache(&addr_to_delete);
 379  364                  (void) rw_unlock(&rpcbaddr_cache_lock);
 380  365                  free(addr_to_delete.buf);
 381  366          }
 382  367          rpcbind_hs.h_host = host;
 383  368          rpcbind_hs.h_serv = "rpcbind";
 384      -#ifdef ND_DEBUG
 385      -        fprintf(stderr, "rpcbind client routines: diagnostics :\n");
 386      -        fprintf(stderr, "\tGetting address for (%s, %s, %s) ... \n",
 387      -                rpcbind_hs.h_host, rpcbind_hs.h_serv, nconf->nc_netid);
 388      -#endif
 389  369  
 390  370          if ((neterr = netdir_getbyname(nconf, &rpcbind_hs, &nas)) != 0) {
 391  371                  if (neterr == ND_NOHOST)
 392  372                          rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
 393  373                  else
 394  374                          rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE;
 395  375                  return (NULL);
 396  376          }
 397  377          /* XXX nas should perhaps be cached for better performance */
 398  378  
 399  379          for (j = 0; j < nas->n_cnt; j++) {
 400  380                  addr = &(nas->n_addrs[j]);
 401      -#ifdef ND_DEBUG
 402      -{
 403      -        int i;
 404      -        char *ua;
 405      -
 406      -        ua = taddr2uaddr(nconf, &(nas->n_addrs[j]));
 407      -        fprintf(stderr, "Got it [%s]\n", ua);
 408      -        free(ua);
 409      -
 410      -        fprintf(stderr, "\tnetbuf len = %d, maxlen = %d\n",
 411      -                addr->len, addr->maxlen);
 412      -        fprintf(stderr, "\tAddress is ");
 413      -        for (i = 0; i < addr->len; i++)
 414      -                fprintf(stderr, "%u.", addr->buf[i]);
 415      -        fprintf(stderr, "\n");
 416      -}
 417      -#endif
 418  381          client = _clnt_tli_create_timed(RPC_ANYFD, nconf, addr, RPCBPROG,
 419      -                                RPCBVERS4, 0, 0, tp);
      382 +            RPCBVERS4, 0, 0, tp);
 420  383          if (client)
 421  384                  break;
 422  385          }
 423      -#ifdef ND_DEBUG
 424      -        if (!client) {
 425      -                clnt_pcreateerror("rpcbind clnt interface");
 426      -        }
 427      -#endif
 428  386  
 429  387          if (client) {
 430  388                  tmpaddr = targaddr ? taddr2uaddr(nconf, addr) : NULL;
 431  389                  add_cache(host, nconf->nc_netid, addr, tmpaddr);
 432  390                  if (targaddr) {
 433  391                          *targaddr = tmpaddr;
 434  392                  }
 435  393          }
 436  394          netdir_free((char *)nas, ND_ADDRLIST);
 437  395          return (client);
 438  396  }
 439  397  
 440  398  /*
 441  399   * This routine will return a client handle that is connected to the local
 442      - * rpcbind. Returns NULL on error and free's everything.
      400 + * rpcbind. Returns NULL on error.
 443  401   */
 444  402  static CLIENT *
 445  403  local_rpcb(void)
 446  404  {
 447  405          static struct netconfig *loopnconf;
 448  406          static char *hostname;
 449  407          extern mutex_t loopnconf_lock;
 450  408  
 451      -/* VARIABLES PROTECTED BY loopnconf_lock: loopnconf */
      409 +/* VARIABLES PROTECTED BY loopnconf_lock: hostname loopnconf */
 452  410          (void) mutex_lock(&loopnconf_lock);
 453  411          if (loopnconf == NULL) {
 454  412                  struct utsname utsname;
 455  413                  struct netconfig *nconf, *tmpnconf = NULL;
 456  414                  void *nc_handle;
 457  415  
 458  416                  if (hostname == NULL) {
 459  417  #if defined(__i386) && !defined(__amd64)
 460  418                          if ((_nuname(&utsname) == -1) ||
      419 +                            ((hostname = strdup(utsname.nodename)) == NULL)) {
 461  420  #else
 462  421                          if ((uname(&utsname) == -1) ||
 463      -#endif
 464  422                              ((hostname = strdup(utsname.nodename)) == NULL)) {
      423 +#endif
 465  424                                  syslog(LOG_ERR, "local_rpcb : strdup failed.");
 466  425                                  rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
 467  426                                  (void) mutex_unlock(&loopnconf_lock);
 468  427                                  return (NULL);
 469  428                          }
      429 +                        /* hostname is never freed */
 470  430                  }
 471  431                  nc_handle = setnetconfig();
 472  432                  if (nc_handle == NULL) {
 473  433                          /* fails to open netconfig file */
 474  434                          rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
 475  435                          (void) mutex_unlock(&loopnconf_lock);
 476  436                          return (NULL);
 477  437                  }
 478  438                  while (nconf = getnetconfig(nc_handle)) {
 479  439                          if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
↓ open down ↓ 35 lines elided ↑ open up ↑
 515  475          }
 516  476          if (address == NULL) {
 517  477                  rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
 518  478                  return (FALSE);
 519  479          }
 520  480          client = local_rpcb();
 521  481          if (!client)
 522  482                  return (FALSE);
 523  483  
 524  484          parms.r_addr = taddr2uaddr((struct netconfig *)nconf,
 525      -                        (struct netbuf *)address); /* convert to universal */
      485 +            (struct netbuf *)address); /* convert to universal */
 526  486          if (!parms.r_addr) {
 527  487                  rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE;
 528  488                  return (FALSE); /* no universal address */
 529  489          }
 530  490          parms.r_prog = program;
 531  491          parms.r_vers = version;
 532  492          parms.r_netid = nconf->nc_netid;
 533  493          /*
 534  494           * Though uid is not being used directly, we still send it for
 535  495           * completeness.  For non-unix platforms, perhaps some other
 536  496           * string or an empty string can be sent.
 537  497           */
 538  498          (void) sprintf(uidbuf, "%d", (int)geteuid());
 539  499          parms.r_owner = uidbuf;
 540  500  
 541  501          CLNT_CALL(client, RPCBPROC_SET, (xdrproc_t)xdr_rpcb, (char *)&parms,
 542      -                        (xdrproc_t)xdr_bool, (char *)&rslt, tottimeout);
      502 +            (xdrproc_t)xdr_bool, (char *)&rslt, tottimeout);
 543  503  
 544  504          CLNT_DESTROY(client);
 545  505          free(parms.r_addr);
 546  506          return (rslt);
 547  507  }
 548  508  
 549  509  /*
 550  510   * Remove the mapping between program, version and netbuf address.
 551  511   * Calls the rpcbind service to do the un-mapping.
 552  512   * If netbuf is NULL, unset for all the transports, otherwise unset
↓ open down ↓ 16 lines elided ↑ open up ↑
 569  529          parms.r_vers = version;
 570  530          if (nconf)
 571  531                  parms.r_netid = nconf->nc_netid;
 572  532          else
 573  533                  parms.r_netid = (char *)&nullstring[0]; /* unsets  all */
 574  534          parms.r_addr = (char *)&nullstring[0];
 575  535          (void) sprintf(uidbuf, "%d", (int)geteuid());
 576  536          parms.r_owner = uidbuf;
 577  537  
 578  538          CLNT_CALL(client, RPCBPROC_UNSET, (xdrproc_t)xdr_rpcb, (char *)&parms,
 579      -                        (xdrproc_t)xdr_bool, (char *)&rslt, tottimeout);
      539 +            (xdrproc_t)xdr_bool, (char *)&rslt, tottimeout);
 580  540  
 581  541          CLNT_DESTROY(client);
 582  542          return (rslt);
 583  543  }
 584  544  
 585  545  /*
 586  546   * From the merged list, find the appropriate entry
 587  547   */
 588  548  static struct netbuf *
 589  549  got_entry(rpcb_entry_list_ptr relp, struct netconfig *nconf)
↓ open down ↓ 2 lines elided ↑ open up ↑
 592  552          rpcb_entry_list_ptr sp;
 593  553          rpcb_entry *rmap;
 594  554  
 595  555          for (sp = relp; sp != NULL; sp = sp->rpcb_entry_next) {
 596  556                  rmap = &sp->rpcb_entry_map;
 597  557                  if ((strcmp(nconf->nc_proto, rmap->r_nc_proto) == 0) &&
 598  558                      (strcmp(nconf->nc_protofmly, rmap->r_nc_protofmly) == 0) &&
 599  559                      (nconf->nc_semantics == rmap->r_nc_semantics) &&
 600  560                      (rmap->r_maddr != NULL) && (rmap->r_maddr[0] != NULL)) {
 601  561                          na = uaddr2taddr(nconf, rmap->r_maddr);
 602      -#ifdef ND_DEBUG
 603      -                        fprintf(stderr, "\tRemote address is [%s].\n",
 604      -                                rmap->r_maddr);
 605      -                        if (!na)
 606      -                                fprintf(stderr,
 607      -                                    "\tCouldn't resolve remote address!\n");
 608      -#endif
 609  562                          break;
 610  563                  }
 611  564          }
 612  565          return (na);
 613  566  }
 614  567  
 615  568  /*
 616  569   * Quick check to see if rpcbind is up.  Tries to connect over
 617  570   * local transport.
 618  571   */
↓ open down ↓ 60 lines elided ↑ open up ↑
 679  632          (void) t_free((char *)sndcall, T_CALL);
 680  633          free(addr->buf);
 681  634          free(addr);
 682  635          (void) t_close(fd);
 683  636  
 684  637          return (res);
 685  638  }
 686  639  
 687  640  
 688  641  /*
 689      - * An internal function which optimizes rpcb_getaddr function.  It also
      642 + * An internal function which optimizes rpcb_getaddr function.  It returns
      643 + * the universal address of the remote service or NULL.  It also optionally
 690  644   * returns the client handle that it uses to contact the remote rpcbind.
      645 + * The caller will re-purpose the client to contact the remote service.
 691  646   *
 692      - * The algorithm used: If the transports is TCP or UDP, it first tries
 693      - * version 2 (portmap), 4 and then 3 (svr4).  This order should be
 694      - * changed in the next OS release to 4, 2 and 3.  We are assuming that by
 695      - * that time, version 4 would be available on many machines on the network.
      647 + * The algorithm used: First try version 4.  Then try version 3 (svr4).
      648 + * Finally, if the transport is TCP or UDP, try version 2 (portmap).
      649 + * Version 4 is now available with all current systems on the network.
 696  650   * With this algorithm, we get performance as well as a plan for
 697  651   * obsoleting version 2.
 698  652   *
 699      - * For all other transports, the algorithm remains as 4 and then 3.
 700      - *
 701  653   * XXX: Due to some problems with t_connect(), we do not reuse the same client
 702  654   * handle for COTS cases and hence in these cases we do not return the
 703  655   * client handle.  This code will change if t_connect() ever
 704  656   * starts working properly.  Also look under clnt_vc.c.
 705  657   */
 706  658  struct netbuf *
 707  659  __rpcb_findaddr_timed(rpcprog_t program, rpcvers_t version,
 708  660          struct netconfig *nconf, char *host, CLIENT **clpp, struct timeval *tp)
 709  661  {
 710  662          static bool_t check_rpcbind = TRUE;
 711  663          CLIENT *client = NULL;
 712  664          RPCB parms;
 713  665          enum clnt_stat clnt_st;
 714  666          char *ua = NULL;
 715  667          uint_t vers;
 716  668          struct netbuf *address = NULL;
 717      -        uint_t start_vers = RPCBVERS4;
      669 +        void *handle;
      670 +        rpcb_entry_list_ptr relp = NULL;
      671 +        bool_t tmp_client = FALSE;
 718  672  
 719  673          /* parameter checking */
 720  674          if (nconf == NULL) {
 721  675                  rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
 722  676                  return (NULL);
 723  677          }
 724  678  
 725  679          parms.r_addr = NULL;
 726  680  
 727  681          /*
 728  682           * Use default total timeout if no timeout is specified.
 729  683           */
 730  684          if (tp == NULL)
 731  685                  tp = &tottimeout;
 732  686  
 733      -#ifdef PORTMAP
 734      -        /* Try version 2 for TCP or UDP */
 735      -        if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
 736      -                ushort_t port = 0;
 737      -                struct netbuf remote;
 738      -                uint_t pmapvers = 2;
 739      -                struct pmap pmapparms;
 740      -
 741      -                /*
 742      -                 * Try UDP only - there are some portmappers out
 743      -                 * there that use UDP only.
 744      -                 */
 745      -                if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
 746      -                        struct netconfig *newnconf;
 747      -                        void *handle;
 748      -
 749      -                        if ((handle = __rpc_setconf("udp")) == NULL) {
 750      -                                rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
 751      -                                return (NULL);
 752      -                        }
 753      -
 754      -                        /*
 755      -                         * The following to reinforce that you can
 756      -                         * only request for remote address through
 757      -                         * the same transport you are requesting.
 758      -                         * ie. requesting unversial address
 759      -                         * of IPv4 has to be carried through IPv4.
 760      -                         * Can't use IPv6 to send out the request.
 761      -                         * The mergeaddr in rpcbind can't handle
 762      -                         * this.
 763      -                         */
 764      -                        for (;;) {
 765      -                                if ((newnconf = __rpc_getconf(handle))
 766      -                                                                    == NULL) {
 767      -                                        __rpc_endconf(handle);
 768      -                                        rpc_createerr.cf_stat =
 769      -                                            RPC_UNKNOWNPROTO;
 770      -                                        return (NULL);
 771      -                                }
 772      -                                /*
 773      -                                 * here check the protocol family to
 774      -                                 * be consistent with the request one
 775      -                                 */
 776      -                                if (strcmp(newnconf->nc_protofmly,
 777      -                                    nconf->nc_protofmly) == NULL)
 778      -                                        break;
 779      -                        }
 780      -
 781      -                        client = _getclnthandle_timed(host, newnconf,
 782      -                                        &parms.r_addr, tp);
 783      -                        __rpc_endconf(handle);
 784      -                } else {
 785      -                        client = _getclnthandle_timed(host, nconf,
 786      -                                        &parms.r_addr, tp);
 787      -                }
 788      -                if (client == NULL)
 789      -                        return (NULL);
 790      -
 791      -                /*
 792      -                 * Set version and retry timeout.
 793      -                 */
 794      -                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime);
 795      -                CLNT_CONTROL(client, CLSET_VERS, (char *)&pmapvers);
 796      -
 797      -                pmapparms.pm_prog = program;
 798      -                pmapparms.pm_vers = version;
 799      -                pmapparms.pm_prot = strcmp(nconf->nc_proto, NC_TCP) ?
 800      -                                    IPPROTO_UDP : IPPROTO_TCP;
 801      -                pmapparms.pm_port = 0;  /* not needed */
 802      -                clnt_st = CLNT_CALL(client, PMAPPROC_GETPORT,
 803      -                                    (xdrproc_t)xdr_pmap, (caddr_t)&pmapparms,
 804      -                                    (xdrproc_t)xdr_u_short, (caddr_t)&port,
 805      -                                    *tp);
 806      -                if (clnt_st != RPC_SUCCESS) {
 807      -                        if ((clnt_st == RPC_PROGVERSMISMATCH) ||
 808      -                            (clnt_st == RPC_PROGUNAVAIL))
 809      -                                goto try_rpcbind; /* Try different versions */
 810      -                        rpc_createerr.cf_stat = RPC_PMAPFAILURE;
 811      -                        clnt_geterr(client, &rpc_createerr.cf_error);
 812      -                        goto error;
 813      -                } else if (port == 0) {
 814      -                        address = NULL;
 815      -                        rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
 816      -                        goto error;
 817      -                }
 818      -                port = htons(port);
 819      -                CLNT_CONTROL(client, CLGET_SVC_ADDR, (char *)&remote);
 820      -                if (((address = malloc(sizeof (struct netbuf))) == NULL) ||
 821      -                    ((address->buf = malloc(remote.len)) == NULL)) {
 822      -                        rpc_createerr.cf_stat = RPC_SYSTEMERROR;
 823      -                        clnt_geterr(client, &rpc_createerr.cf_error);
 824      -                        if (address) {
 825      -                                free(address);
 826      -                                address = NULL;
 827      -                        }
 828      -                        goto error;
 829      -                }
 830      -                (void) memcpy(address->buf, remote.buf, remote.len);
 831      -                (void) memcpy(&address->buf[sizeof (short)], &port,
 832      -                                                                sizeof (short));
 833      -                address->len = address->maxlen = remote.len;
 834      -                goto done;
 835      -        }
 836      -#endif
 837      -
 838      -try_rpcbind:
 839  687          /*
 840  688           * Check if rpcbind is up.  This prevents needless delays when
 841  689           * accessing applications such as the keyserver while booting
 842  690           * disklessly.
 843  691           */
 844  692          if (check_rpcbind && strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
 845  693                  if (!__rpcbind_is_up()) {
 846  694                          rpc_createerr.cf_stat = RPC_PMAPFAILURE;
 847  695                          rpc_createerr.cf_error.re_errno = 0;
 848  696                          rpc_createerr.cf_error.re_terrno = 0;
 849  697                          goto error;
 850  698                  }
 851  699                  check_rpcbind = FALSE;
 852  700          }
 853  701  
 854  702          /*
 855      -         * Now we try version 4 and then 3.
 856      -         * We also send the remote system the address we used to
 857      -         * contact it in case it can help to connect back with us
      703 +         * First try version 4.
 858  704           */
 859  705          parms.r_prog = program;
 860  706          parms.r_vers = version;
 861  707          parms.r_owner = (char *)&nullstring[0]; /* not needed; */
 862  708          /* just for xdring */
 863  709          parms.r_netid = nconf->nc_netid; /* not really needed */
 864  710  
 865  711          /*
 866  712           * If a COTS transport is being used, try getting address via CLTS
 867  713           * transport.  This works only with version 4.
 868  714           */
 869  715          if (nconf->nc_semantics == NC_TPI_COTS_ORD ||
 870  716              nconf->nc_semantics == NC_TPI_COTS) {
 871      -                void *handle;
 872      -                struct netconfig *nconf_clts;
 873      -                rpcb_entry_list_ptr relp = NULL;
      717 +                tmp_client = TRUE;
      718 +                if ((handle = __rpc_setconf("datagram_v")) != NULL) {
      719 +                        struct netconfig *nconf_clts;
 874  720  
 875      -                if (client == NULL) {
 876      -                        /* This did not go through the above PORTMAP/TCP code */
 877      -                        if ((handle = __rpc_setconf("datagram_v")) != NULL) {
 878      -                                while ((nconf_clts = __rpc_getconf(handle))
 879      -                                    != NULL) {
 880      -                                        if (strcmp(nconf_clts->nc_protofmly,
 881      -                                            nconf->nc_protofmly) != 0) {
 882      -                                                continue;
 883      -                                        }
 884      -                                        client = _getclnthandle_timed(host,
 885      -                                                nconf_clts, &parms.r_addr,
 886      -                                                tp);
 887      -                                        break;
      721 +                        while ((nconf_clts = __rpc_getconf(handle)) != NULL) {
      722 +                                if (strcmp(nconf_clts->nc_protofmly,
      723 +                                    nconf->nc_protofmly) != 0) {
      724 +                                        continue;
 888  725                                  }
 889      -                                __rpc_endconf(handle);
      726 +                                client = _getclnthandle_timed(host, nconf_clts,
      727 +                                    &parms.r_addr, tp);
      728 +                                break;
 890  729                          }
 891      -                        if (client == NULL)
 892      -                                goto regular_rpcbind;   /* Go the regular way */
 893      -                } else {
 894      -                        /* This is a UDP PORTMAP handle.  Change to version 4 */
 895      -                        vers = RPCBVERS4;
 896      -                        CLNT_CONTROL(client, CLSET_VERS, (char *)&vers);
      730 +                        __rpc_endconf(handle);
 897  731                  }
      732 +        } else {
      733 +                client = _getclnthandle_timed(host, nconf, &parms.r_addr, tp);
      734 +                /* Sets cf_error members on failure */
      735 +        }
      736 +
      737 +        if (client != NULL) {
      738 +
      739 +                /* Set rpcbind version 4 */
      740 +                vers = RPCBVERS4;
      741 +                CLNT_CONTROL(client, CLSET_VERS, (char *)&vers);
      742 +
 898  743                  /*
 899  744                   * We also send the remote system the address we used to
 900  745                   * contact it in case it can help it connect back with us
 901  746                   */
 902  747                  if (parms.r_addr == NULL) {
 903  748                          parms.r_addr = strdup(""); /* for XDRing */
 904  749                          if (parms.r_addr == NULL) {
 905  750                                  syslog(LOG_ERR, "__rpcb_findaddr_timed: "
 906      -                                        "strdup failed.");
      751 +                                    "strdup failed.");
      752 +                                /* cf_error is still zeroed */
      753 +                                rpc_createerr.cf_error.re_errno = errno;
 907  754                                  rpc_createerr.cf_stat = RPC_SYSTEMERROR;
 908      -                                address = NULL;
 909  755                                  goto error;
 910  756                          }
 911  757                  }
 912  758  
 913      -                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime);
      759 +                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT,
      760 +                    (char *)&rpcbrmttime);
 914  761  
 915  762                  clnt_st = CLNT_CALL(client, RPCBPROC_GETADDRLIST,
 916      -                                    (xdrproc_t)xdr_rpcb, (char *)&parms,
 917      -                                    (xdrproc_t)xdr_rpcb_entry_list_ptr,
 918      -                                    (char *)&relp, *tp);
 919      -                if (clnt_st == RPC_SUCCESS) {
 920      -                        if (address = got_entry(relp, nconf)) {
 921      -                                xdr_free((xdrproc_t)xdr_rpcb_entry_list_ptr,
 922      -                                        (char *)&relp);
      763 +                    (xdrproc_t)xdr_rpcb, (char *)&parms,
      764 +                    (xdrproc_t)xdr_rpcb_entry_list_ptr, (char *)&relp, *tp);
      765 +                /* Sets error structure members in client handle */
      766 +                switch (clnt_st) {
      767 +                case RPC_SUCCESS: /* Call succeeded */
      768 +                        address = got_entry(relp, nconf);
      769 +                        xdr_free((xdrproc_t)xdr_rpcb_entry_list_ptr,
      770 +                            (char *)&relp);
      771 +                        if (address != NULL) {
      772 +                                /* Program number and version number matched */
 923  773                                  goto done;
 924  774                          }
 925      -                        /* Entry not found for this transport */
 926      -                        xdr_free((xdrproc_t)xdr_rpcb_entry_list_ptr,
 927      -                                    (char *)&relp);
      775 +                        /* Program and version not found for this transport */
 928  776                          /*
 929      -                         * XXX: should have perhaps returned with error but
      777 +                         * XXX: should have returned with RPC_PROGUNAVAIL
      778 +                         * or perhaps RPC_PROGNOTREGISTERED error but
 930  779                           * since the remote machine might not always be able
 931  780                           * to send the address on all transports, we try the
 932      -                         * regular way with regular_rpcbind
      781 +                         * regular way with version 3, then 2
 933  782                           */
 934      -                        goto regular_rpcbind;
 935      -                } else if ((clnt_st == RPC_PROGVERSMISMATCH) ||
 936      -                            (clnt_st == RPC_PROGUNAVAIL)) {
 937      -                        start_vers = RPCBVERS;  /* Try version 3 now */
 938      -                        goto regular_rpcbind; /* Try different versions */
 939      -                } else {
 940      -                        rpc_createerr.cf_stat = RPC_PMAPFAILURE;
      783 +                        /* Try the next version */
      784 +                        break;
      785 +                case RPC_PROGVERSMISMATCH: /* RPC protocol mismatch */
 941  786                          clnt_geterr(client, &rpc_createerr.cf_error);
      787 +                        if (rpc_createerr.cf_error.re_vers.low > vers) {
      788 +                                rpc_createerr.cf_stat = clnt_st;
      789 +                                goto error;  /* a new version, can't handle */
      790 +                        }
      791 +                        /* Try the next version */
      792 +                        break;
      793 +                case RPC_PROCUNAVAIL: /* Procedure unavailable */
      794 +                case RPC_PROGUNAVAIL: /* Program not available */
      795 +                case RPC_TIMEDOUT: /* Call timed out */
      796 +                        /* Try the next version */
      797 +                        break;
      798 +                default:
      799 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      800 +                        rpc_createerr.cf_stat = RPC_PMAPFAILURE;
 942  801                          goto error;
      802 +                        break;
 943  803                  }
 944      -        }
 945  804  
 946      -regular_rpcbind:
      805 +        } else {
 947  806  
 948      -        /* Now the same transport is to be used to get the address */
 949      -        if (client && ((nconf->nc_semantics == NC_TPI_COTS_ORD) ||
 950      -            (nconf->nc_semantics == NC_TPI_COTS))) {
 951      -                /* A CLTS type of client - destroy it */
      807 +                /* No client */
      808 +                tmp_client = FALSE;
      809 +
      810 +        } /* End of version 4 */
      811 +
      812 +        /* Destroy a temporary client */
      813 +        if (client != NULL && tmp_client) {
 952  814                  CLNT_DESTROY(client);
 953  815                  client = NULL;
 954  816                  free(parms.r_addr);
 955  817                  parms.r_addr = NULL;
 956  818          }
      819 +        tmp_client = FALSE;
 957  820  
      821 +        /*
      822 +         * Try version 3
      823 +         */
      824 +
      825 +        /* Now the same transport is to be used to get the address */
 958  826          if (client == NULL) {
 959  827                  client = _getclnthandle_timed(host, nconf, &parms.r_addr, tp);
 960      -                if (client == NULL) {
 961      -                        address = NULL;
 962      -                        goto error;
 963      -                }
      828 +                /* Sets cf_error members on failure */
 964  829          }
 965      -        if (parms.r_addr == NULL) {
 966      -                parms.r_addr = strdup("");      /* for XDRing */
      830 +        address = NULL;
      831 +        if (client != NULL) {
 967  832                  if (parms.r_addr == NULL) {
 968      -                        syslog(LOG_ERR, "__rpcb_findaddr_timed: "
 969      -                                "strdup failed.");
 970      -                        address = NULL;
 971      -                        rpc_createerr.cf_stat = RPC_SYSTEMERROR;
 972      -                        goto error;
      833 +                        parms.r_addr = strdup("");      /* for XDRing */
      834 +                        if (parms.r_addr == NULL) {
      835 +                                syslog(LOG_ERR, "__rpcb_findaddr_timed: "
      836 +                                    "strdup failed.");
      837 +                                /* cf_error is still zeroed */
      838 +                                rpc_createerr.cf_error.re_errno = errno;
      839 +                                rpc_createerr.cf_stat = RPC_SYSTEMERROR;
      840 +                                goto error;
      841 +                        }
 973  842                  }
 974      -        }
 975  843  
 976      -        /* First try from start_vers and then version 3 (RPCBVERS) */
 977      -
 978      -        CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime);
 979      -        for (vers = start_vers;  vers >= RPCBVERS; vers--) {
 980      -                /* Set the version */
      844 +                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT,
      845 +                    (char *)&rpcbrmttime);
      846 +                vers = RPCBVERS; /* Set the version */
 981  847                  CLNT_CONTROL(client, CLSET_VERS, (char *)&vers);
 982  848                  clnt_st = CLNT_CALL(client, RPCBPROC_GETADDR,
 983      -                                    (xdrproc_t)xdr_rpcb, (char *)&parms,
 984      -                                    (xdrproc_t)xdr_wrapstring,
 985      -                                    (char *)&ua, *tp);
 986      -                if (clnt_st == RPC_SUCCESS) {
 987      -                        if ((ua == NULL) || (ua[0] == NULL)) {
 988      -                                if (ua != NULL)
 989      -                                        xdr_free(xdr_wrapstring, (char *)&ua);
      849 +                    (xdrproc_t)xdr_rpcb, (char *)&parms,
      850 +                    (xdrproc_t)xdr_wrapstring, (char *)&ua, *tp);
      851 +                /* Sets error structure members in client handle */
      852 +                switch (clnt_st) {
      853 +                case RPC_SUCCESS: /* Call succeeded */
      854 +                        if (ua != NULL) {
      855 +                                if (ua[0] != '\0') {
      856 +                                        address = uaddr2taddr(nconf, ua);
      857 +                                }
      858 +                                xdr_free((xdrproc_t)xdr_wrapstring,
      859 +                                    (char *)&ua);
 990  860  
 991      -                                /* address unknown */
      861 +                                if (address != NULL) {
      862 +                                        goto done;
      863 +                                }
      864 +                                /* We don't know about your universal addr */
      865 +                                /* cf_error is still zeroed */
 992  866                                  rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
 993  867                                  goto error;
 994  868                          }
 995      -                        address = uaddr2taddr(nconf, ua);
 996      -#ifdef ND_DEBUG
 997      -                        fprintf(stderr, "\tRemote address is [%s]\n", ua);
 998      -                        if (!address)
 999      -                                fprintf(stderr,
1000      -                                        "\tCouldn't resolve remote address!\n");
      869 +#ifndef PORTMAP
      870 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      871 +                        rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
      872 +                        goto error;
1001  873  #endif
1002      -                        xdr_free((xdrproc_t)xdr_wrapstring, (char *)&ua);
      874 +                        /* Try the next version */
      875 +                        break;
      876 +                case RPC_PROGVERSMISMATCH: /* RPC protocol mismatch */
      877 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      878 +#ifdef PORTMAP
      879 +                        if (rpc_createerr.cf_error.re_vers.low > vers) {
      880 +                                rpc_createerr.cf_stat = clnt_st;
      881 +                                goto error;  /* a new version, can't handle */
      882 +                        }
      883 +#else
      884 +                        rpc_createerr.cf_stat = clnt_st;
      885 +                        goto error;
      886 +#endif
      887 +                        /* Try the next version */
      888 +                        break;
      889 +#ifdef PORTMAP
      890 +                case RPC_PROCUNAVAIL: /* Procedure unavailable */
      891 +                case RPC_PROGUNAVAIL: /* Program not available */
      892 +                case RPC_TIMEDOUT: /* Call timed out */
      893 +                        /* Try the next version */
      894 +                        break;
      895 +#endif
      896 +                default:
      897 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      898 +                        rpc_createerr.cf_stat = RPC_PMAPFAILURE;
      899 +                        goto error;
      900 +                        break;
      901 +                }
      902 +        } /* End of version 3 */
      903 +#ifndef PORTMAP
      904 +        /* cf_error members set by creation failure */
      905 +        rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
      906 +#endif
      907 +        /*
      908 +         * Try version 2
      909 +         */
1003  910  
1004      -                        if (!address) {
1005      -                                /* We don't know about your universal address */
1006      -                                rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE;
      911 +#ifdef PORTMAP
      912 +        /* Try version 2 for TCP or UDP */
      913 +        if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
      914 +                ushort_t port = 0;
      915 +                struct netbuf remote;
      916 +                uint_t pmapvers = 2;
      917 +                struct pmap pmapparms;
      918 +
      919 +                /*
      920 +                 * Try UDP only - there are some portmappers out
      921 +                 * there that use UDP only.
      922 +                 */
      923 +                if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
      924 +                        struct netconfig *newnconf;
      925 +
      926 +                        if (client != NULL) {
      927 +                                CLNT_DESTROY(client);
      928 +                                client = NULL;
      929 +                                free(parms.r_addr);
      930 +                                parms.r_addr = NULL;
      931 +                        }
      932 +                        if ((handle = __rpc_setconf("udp")) == NULL) {
      933 +                                /* cf_error is still zeroed */
      934 +                                rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
1007  935                                  goto error;
1008  936                          }
1009      -                        goto done;
      937 +
      938 +                        /*
      939 +                         * The following to reinforce that you can
      940 +                         * only request for remote address through
      941 +                         * the same transport you are requesting.
      942 +                         * ie. requesting unversial address
      943 +                         * of IPv4 has to be carried through IPv4.
      944 +                         * Can't use IPv6 to send out the request.
      945 +                         * The mergeaddr in rpcbind can't handle
      946 +                         * this.
      947 +                         */
      948 +                        for (;;) {
      949 +                                if ((newnconf = __rpc_getconf(handle))
      950 +                                    == NULL) {
      951 +                                        __rpc_endconf(handle);
      952 +                                        /* cf_error is still zeroed */
      953 +                                        rpc_createerr.cf_stat =
      954 +                                            RPC_UNKNOWNPROTO;
      955 +                                        goto error;
      956 +                                }
      957 +                                /*
      958 +                                 * here check the protocol family to
      959 +                                 * be consistent with the request one
      960 +                                 */
      961 +                                if (strcmp(newnconf->nc_protofmly,
      962 +                                    nconf->nc_protofmly) == 0)
      963 +                                        break;
      964 +                        }
      965 +
      966 +                        client = _getclnthandle_timed(host, newnconf,
      967 +                            &parms.r_addr, tp);
      968 +                        /* Sets cf_error members on failure */
      969 +                        __rpc_endconf(handle);
      970 +                        tmp_client = TRUE;
1010  971                  }
1011      -                if (clnt_st == RPC_PROGVERSMISMATCH) {
1012      -                        struct rpc_err rpcerr;
      972 +                if (client == NULL) {
      973 +                        /* cf_error members set by creation failure */
      974 +                        rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
      975 +                        tmp_client = FALSE;
      976 +                        goto error;
      977 +                }
1013  978  
1014      -                        clnt_geterr(client, &rpcerr);
1015      -                        if (rpcerr.re_vers.low > RPCBVERS4)
1016      -                                goto error;  /* a new version, can't handle */
1017      -                } else if (clnt_st != RPC_PROGUNAVAIL) {
1018      -                        /* Cant handle this error */
      979 +                /*
      980 +                 * Set version and retry timeout.
      981 +                 */
      982 +                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime);
      983 +                CLNT_CONTROL(client, CLSET_VERS, (char *)&pmapvers);
      984 +
      985 +                pmapparms.pm_prog = program;
      986 +                pmapparms.pm_vers = version;
      987 +                pmapparms.pm_prot = (strcmp(nconf->nc_proto, NC_TCP) != 0) ?
      988 +                    IPPROTO_UDP : IPPROTO_TCP;
      989 +                pmapparms.pm_port = 0;  /* not needed */
      990 +                clnt_st = CLNT_CALL(client, PMAPPROC_GETPORT,
      991 +                    (xdrproc_t)xdr_pmap, (caddr_t)&pmapparms,
      992 +                    (xdrproc_t)xdr_u_short, (caddr_t)&port, *tp);
      993 +                /* Sets error structure members in client handle */
      994 +                if (clnt_st != RPC_SUCCESS) {
      995 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      996 +                        rpc_createerr.cf_stat = RPC_RPCBFAILURE;
1019  997                          goto error;
      998 +                } else if (port == 0) {
      999 +                        /* cf_error is still zeroed */
     1000 +                        rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
     1001 +                        goto error;
1020 1002                  }
     1003 +                port = htons(port);
     1004 +                CLNT_CONTROL(client, CLGET_SVC_ADDR, (char *)&remote);
     1005 +                if (((address = malloc(sizeof (struct netbuf))) == NULL) ||
     1006 +                    ((address->buf = malloc(remote.len)) == NULL)) {
     1007 +                        /* cf_error is still zeroed */
     1008 +                        rpc_createerr.cf_error.re_errno = errno;
     1009 +                        rpc_createerr.cf_stat = RPC_SYSTEMERROR;
     1010 +                        free(address);
     1011 +                        address = NULL;
     1012 +                        goto error;
     1013 +                }
     1014 +                (void) memcpy(address->buf, remote.buf, remote.len);
     1015 +                (void) memcpy(&address->buf[sizeof (short)], &port,
     1016 +                    sizeof (short));
     1017 +                address->len = address->maxlen = remote.len;
     1018 +                goto done;
     1019 +        } else {
     1020 +                /* Not NC_INET */
     1021 +                if (client != NULL && clnt_st != RPC_SUCCESS) {
     1022 +                        clnt_geterr(client, &rpc_createerr.cf_error);
     1023 +                        rpc_createerr.cf_stat = clnt_st;
     1024 +                } else {
     1025 +                        /* No client handle */
     1026 +                        rpc_createerr.cf_stat = RPC_SYSTEMERROR;
     1027 +                }
1021 1028          }
     1029 +#endif
1022 1030  
1023      -        if ((address == NULL) || (address->len == 0)) {
1024      -                rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
1025      -                clnt_geterr(client, &rpc_createerr.cf_error);
1026      -        }
1027      -
1028 1031  error:
1029      -        if (client) {
     1032 +        /* Return NULL address and NULL client */
     1033 +        address = NULL;
     1034 +        if (client != NULL) {
1030 1035                  CLNT_DESTROY(client);
1031 1036                  client = NULL;
1032 1037          }
     1038 +
1033 1039  done:
1034      -        if (nconf->nc_semantics != NC_TPI_CLTS) {
1035      -                /* This client is the connectionless one */
1036      -                if (client) {
1037      -                        CLNT_DESTROY(client);
1038      -                        client = NULL;
1039      -                }
     1040 +        /* Return an address and optional client */
     1041 +        if (client != NULL && tmp_client) {
     1042 +                /* This client is the temporary one */
     1043 +                CLNT_DESTROY(client);
     1044 +                client = NULL;
1040 1045          }
1041      -        if (clpp) {
     1046 +        if (clpp != NULL) {
1042 1047                  *clpp = client;
1043      -        } else if (client) {
     1048 +        } else if (client != NULL) {
1044 1049                  CLNT_DESTROY(client);
1045 1050          }
1046      -        if (parms.r_addr)
1047      -                free(parms.r_addr);
     1051 +        free(parms.r_addr);
1048 1052          return (address);
1049 1053  }
1050 1054  
1051 1055  
1052 1056  /*
1053 1057   * Find the mapped address for program, version.
1054 1058   * Calls the rpcbind service remotely to do the lookup.
1055 1059   * Uses the transport specified in nconf.
1056 1060   * Returns FALSE (0) if no map exists, else returns 1.
1057 1061   *
↓ open down ↓ 30 lines elided ↑ open up ↑
1088 1092   */
1089 1093  rpcblist *
1090 1094  rpcb_getmaps(const struct netconfig *nconf, const char *host)
1091 1095  {
1092 1096          rpcblist_ptr head = NULL;
1093 1097          CLIENT *client;
1094 1098          enum clnt_stat clnt_st;
1095 1099          int vers = 0;
1096 1100  
1097 1101          client = getclnthandle((char *)host,
1098      -                        (struct netconfig *)nconf, NULL);
     1102 +            (struct netconfig *)nconf, NULL);
1099 1103          if (client == NULL)
1100 1104                  return (NULL);
1101 1105  
1102 1106          clnt_st = CLNT_CALL(client, RPCBPROC_DUMP,
1103      -                        (xdrproc_t)xdr_void, NULL,
1104      -                        (xdrproc_t)xdr_rpcblist_ptr,
1105      -                        (char *)&head, tottimeout);
     1107 +            (xdrproc_t)xdr_void, NULL,
     1108 +            (xdrproc_t)xdr_rpcblist_ptr,
     1109 +            (char *)&head, tottimeout);
1106 1110          if (clnt_st == RPC_SUCCESS)
1107 1111                  goto done;
1108 1112  
1109 1113          if ((clnt_st != RPC_PROGVERSMISMATCH) &&
1110      -                    (clnt_st != RPC_PROGUNAVAIL)) {
     1114 +            (clnt_st != RPC_PROGUNAVAIL)) {
1111 1115                  rpc_createerr.cf_stat = RPC_RPCBFAILURE;
1112 1116                  clnt_geterr(client, &rpc_createerr.cf_error);
1113 1117                  goto done;
1114 1118          }
1115 1119  
1116 1120          /* fall back to earlier version */
1117 1121          CLNT_CONTROL(client, CLGET_VERS, (char *)&vers);
1118 1122          if (vers == RPCBVERS4) {
1119 1123                  vers = RPCBVERS;
1120 1124                  CLNT_CONTROL(client, CLSET_VERS, (char *)&vers);
1121 1125                  if (CLNT_CALL(client, RPCBPROC_DUMP,
1122      -                        (xdrproc_t)xdr_void,
1123      -                        NULL, (xdrproc_t)xdr_rpcblist_ptr,
1124      -                        (char *)&head, tottimeout) == RPC_SUCCESS)
     1126 +                    (xdrproc_t)xdr_void,
     1127 +                    NULL, (xdrproc_t)xdr_rpcblist_ptr,
     1128 +                    (char *)&head, tottimeout) == RPC_SUCCESS)
1125 1129                                  goto done;
1126 1130          }
1127 1131          rpc_createerr.cf_stat = RPC_RPCBFAILURE;
1128 1132          clnt_geterr(client, &rpc_createerr.cf_error);
1129 1133  
1130 1134  done:
1131 1135          CLNT_DESTROY(client);
1132 1136          return (head);
1133 1137  }
1134 1138  
↓ open down ↓ 25 lines elided ↑ open up ↑
1160 1164          a.proc = proc;
1161 1165          a.args.args_val = argsp;
1162 1166          a.xdr_args = xdrargs;
1163 1167          r.addr = NULL;
1164 1168          r.results.results_val = resp;
1165 1169          r.xdr_res = xdrres;
1166 1170  
1167 1171          for (rpcb_vers = RPCBVERS4; rpcb_vers >= RPCBVERS; rpcb_vers--) {
1168 1172                  CLNT_CONTROL(client, CLSET_VERS, (char *)&rpcb_vers);
1169 1173                  stat = CLNT_CALL(client, RPCBPROC_CALLIT,
1170      -                        (xdrproc_t)xdr_rpcb_rmtcallargs, (char *)&a,
1171      -                        (xdrproc_t)xdr_rpcb_rmtcallres, (char *)&r, tout);
     1174 +                    (xdrproc_t)xdr_rpcb_rmtcallargs, (char *)&a,
     1175 +                    (xdrproc_t)xdr_rpcb_rmtcallres, (char *)&r, tout);
1172 1176                  if ((stat == RPC_SUCCESS) && (addr_ptr != NULL)) {
1173 1177                          struct netbuf *na;
1174 1178  
1175 1179                          na = uaddr2taddr((struct netconfig *)nconf, r.addr);
1176 1180                          if (!na) {
1177 1181                                  stat = RPC_N2AXLATEFAILURE;
1178 1182                                  ((struct netbuf *)addr_ptr)->len = 0;
1179 1183                                  goto error;
1180 1184                          }
1181 1185                          if (na->len > addr_ptr->maxlen) {
↓ open down ↓ 2 lines elided ↑ open up ↑
1184 1188                                  netdir_free((char *)na, ND_ADDR);
1185 1189                                  ((struct netbuf *)addr_ptr)->len = 0;
1186 1190                                  goto error;
1187 1191                          }
1188 1192                          (void) memcpy(addr_ptr->buf, na->buf, (int)na->len);
1189 1193                          ((struct netbuf *)addr_ptr)->len = na->len;
1190 1194                          netdir_free((char *)na, ND_ADDR);
1191 1195                          break;
1192 1196                  }
1193 1197                  if ((stat != RPC_PROGVERSMISMATCH) &&
1194      -                            (stat != RPC_PROGUNAVAIL))
     1198 +                    (stat != RPC_PROGUNAVAIL))
1195 1199                          goto error;
1196 1200          }
1197 1201  error:
1198 1202          CLNT_DESTROY(client);
1199 1203          if (r.addr)
1200 1204                  xdr_free((xdrproc_t)xdr_wrapstring, (char *)&r.addr);
1201 1205          return (stat);
1202 1206  }
1203 1207  
1204 1208  /*
↓ open down ↓ 27 lines elided ↑ open up ↑
1232 1236                  }
1233 1237                  client = getclnthandle((char *)host, nconf, NULL);
1234 1238                  if (client)
1235 1239                          break;
1236 1240          }
1237 1241          __rpc_endconf(handle);
1238 1242          if (client == NULL)
1239 1243                  return (FALSE);
1240 1244  
1241 1245          st = CLNT_CALL(client, RPCBPROC_GETTIME,
1242      -                (xdrproc_t)xdr_void, NULL,
1243      -                (xdrproc_t)xdr_time_t, (char *)timep, tottimeout);
     1246 +            (xdrproc_t)xdr_void, NULL,
     1247 +            (xdrproc_t)xdr_time_t, (char *)timep, tottimeout);
1244 1248  
1245 1249          if ((st == RPC_PROGVERSMISMATCH) || (st == RPC_PROGUNAVAIL)) {
1246 1250                  CLNT_CONTROL(client, CLGET_VERS, (char *)&vers);
1247 1251                  if (vers == RPCBVERS4) {
1248 1252                          /* fall back to earlier version */
1249 1253                          vers = RPCBVERS;
1250 1254                          CLNT_CONTROL(client, CLSET_VERS, (char *)&vers);
1251 1255                          st = CLNT_CALL(client, RPCBPROC_GETTIME,
1252      -                                (xdrproc_t)xdr_void, NULL,
1253      -                                (xdrproc_t)xdr_time_t, (char *)timep,
1254      -                                tottimeout);
     1256 +                            (xdrproc_t)xdr_void, NULL,
     1257 +                            (xdrproc_t)xdr_time_t, (char *)timep,
     1258 +                            tottimeout);
1255 1259                  }
1256 1260          }
1257 1261          CLNT_DESTROY(client);
1258 1262          return (st == RPC_SUCCESS? TRUE : FALSE);
1259 1263  }
1260 1264  
1261 1265  /*
1262 1266   * Converts taddr to universal address.  This routine should never
1263 1267   * really be called because local n2a libraries are always provided.
1264 1268   */
↓ open down ↓ 10 lines elided ↑ open up ↑
1275 1279          }
1276 1280          if (taddr == NULL) {
1277 1281                  rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
1278 1282                  return (NULL);
1279 1283          }
1280 1284          client = local_rpcb();
1281 1285          if (!client)
1282 1286                  return (NULL);
1283 1287  
1284 1288          CLNT_CALL(client, RPCBPROC_TADDR2UADDR, (xdrproc_t)xdr_netbuf,
1285      -                (char *)taddr, (xdrproc_t)xdr_wrapstring, (char *)&uaddr,
1286      -                tottimeout);
     1289 +            (char *)taddr, (xdrproc_t)xdr_wrapstring, (char *)&uaddr,
     1290 +            tottimeout);
1287 1291          CLNT_DESTROY(client);
1288 1292          return (uaddr);
1289 1293  }
1290 1294  
1291 1295  /*
1292 1296   * Converts universal address to netbuf.  This routine should never
1293 1297   * really be called because local n2a libraries are always provided.
1294 1298   */
1295 1299  struct netbuf *
1296 1300  rpcb_uaddr2taddr(struct netconfig *nconf, char *uaddr)
↓ open down ↓ 14 lines elided ↑ open up ↑
1311 1315          if (!client)
1312 1316                  return (NULL);
1313 1317  
1314 1318          taddr = calloc(1, sizeof (struct netbuf));
1315 1319          if (taddr == NULL) {
1316 1320                  CLNT_DESTROY(client);
1317 1321                  return (NULL);
1318 1322          }
1319 1323  
1320 1324          if (CLNT_CALL(client, RPCBPROC_UADDR2TADDR, (xdrproc_t)xdr_wrapstring,
1321      -                (char *)&uaddr, (xdrproc_t)xdr_netbuf, (char *)taddr,
1322      -                tottimeout) != RPC_SUCCESS) {
     1325 +            (char *)&uaddr, (xdrproc_t)xdr_netbuf, (char *)taddr,
     1326 +            tottimeout) != RPC_SUCCESS) {
1323 1327                  free(taddr);
1324 1328                  taddr = NULL;
1325 1329          }
1326 1330          CLNT_DESTROY(client);
1327 1331          return (taddr);
1328 1332  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX