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;
      717 +                tmp_client = TRUE;
      718 +                handle = __rpc_setconf("datagram_v");
      719 +        } else {
      720 +                handle = __rpc_setconf(nconf->nc_proto);
      721 +        }
      722 +
      723 +        if (handle != NULL) {
 872  724                  struct netconfig *nconf_clts;
 873      -                rpcb_entry_list_ptr relp = NULL;
 874  725  
 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;
 888      -                                }
 889      -                                __rpc_endconf(handle);
      726 +                while ((nconf_clts = __rpc_getconf(handle)) != NULL) {
      727 +                        if (strcmp(nconf_clts->nc_protofmly,
      728 +                            nconf->nc_protofmly) != 0) {
      729 +                                continue;
 890  730                          }
 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);
      731 +                        client = _getclnthandle_timed(host, nconf_clts,
      732 +                            &parms.r_addr, tp);
      733 +                        break;
 897  734                  }
      735 +                __rpc_endconf(handle);
      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.");
 907  752                                  rpc_createerr.cf_stat = RPC_SYSTEMERROR;
 908      -                                address = NULL;
 909  753                                  goto error;
 910  754                          }
 911  755                  }
 912  756  
 913      -                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime);
      757 +                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT,
      758 +                    (char *)&rpcbrmttime);
 914  759  
 915  760                  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);
      761 +                    (xdrproc_t)xdr_rpcb, (char *)&parms,
      762 +                    (xdrproc_t)xdr_rpcb_entry_list_ptr, (char *)&relp, *tp);
      763 +                switch (clnt_st) {
      764 +                case RPC_SUCCESS: /* Call succeeded */
      765 +                        address = got_entry(relp, nconf);
      766 +                        xdr_free((xdrproc_t)xdr_rpcb_entry_list_ptr,
      767 +                            (char *)&relp);
      768 +                        if (address != NULL) {
      769 +                                /* Program number and version number matched */
 923  770                                  goto done;
 924  771                          }
 925      -                        /* Entry not found for this transport */
 926      -                        xdr_free((xdrproc_t)xdr_rpcb_entry_list_ptr,
 927      -                                    (char *)&relp);
      772 +                        /* Program and version not found for this transport */
 928  773                          /*
 929      -                         * XXX: should have perhaps returned with error but
      774 +                         * XXX: should have returned with RPC_PROGUNAVAIL
      775 +                         * or perhaps RPC_PROGNOTREGISTERED error but
 930  776                           * since the remote machine might not always be able
 931  777                           * to send the address on all transports, we try the
 932      -                         * regular way with regular_rpcbind
      778 +                         * regular way with version 3, then 2
 933  779                           */
 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 {
      780 +                        /* Try the next version */
      781 +                        break;
      782 +                case RPC_PROGVERSMISMATCH: /* RPC protocol mismatch */
      783 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      784 +                        if (rpc_createerr.cf_error.re_vers.low > vers) {
      785 +                                rpc_createerr.cf_stat = RPC_PROGVERSMISMATCH;
      786 +                                goto error;  /* a new version, can't handle */
      787 +                        }
      788 +                        /* Try the next version */
      789 +                        break;
      790 +                case RPC_PROCUNAVAIL: /* Procedure unavailable */
      791 +                case RPC_PROGUNAVAIL: /* Program not available */
      792 +                case RPC_TIMEDOUT: /* Call timed out */
      793 +                        /* Try the next version */
      794 +                        break;
      795 +                default:
 940  796                          rpc_createerr.cf_stat = RPC_PMAPFAILURE;
 941  797                          clnt_geterr(client, &rpc_createerr.cf_error);
 942  798                          goto error;
      799 +                        break;
 943  800                  }
 944      -        }
 945  801  
 946      -regular_rpcbind:
      802 +        } else {
 947  803  
 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 */
      804 +                /* No client */
      805 +                tmp_client = FALSE;
      806 +
      807 +        } /* End of version 4 */
      808 +
      809 +        /* Destroy a temporary client */
      810 +        if (client != NULL && tmp_client) {
 952  811                  CLNT_DESTROY(client);
 953  812                  client = NULL;
 954  813                  free(parms.r_addr);
 955  814                  parms.r_addr = NULL;
 956  815          }
      816 +        tmp_client = FALSE;
 957  817  
      818 +        /*
      819 +         * Try version 3
      820 +         */
      821 +
      822 +        /* Now the same transport is to be used to get the address */
 958  823          if (client == NULL) {
 959  824                  client = _getclnthandle_timed(host, nconf, &parms.r_addr, tp);
 960      -                if (client == NULL) {
 961      -                        address = NULL;
 962      -                        goto error;
 963      -                }
 964  825          }
 965      -        if (parms.r_addr == NULL) {
 966      -                parms.r_addr = strdup("");      /* for XDRing */
      826 +        address = NULL;
      827 +        if (client != NULL) {
 967  828                  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;
      829 +                        parms.r_addr = strdup("");      /* for XDRing */
      830 +                        if (parms.r_addr == NULL) {
      831 +                                syslog(LOG_ERR, "__rpcb_findaddr_timed: "
      832 +                                    "strdup failed.");
      833 +                                rpc_createerr.cf_stat = RPC_SYSTEMERROR;
      834 +                                goto error;
      835 +                        }
 973  836                  }
 974      -        }
 975  837  
 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 */
      838 +                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT,
      839 +                    (char *)&rpcbrmttime);
      840 +                vers = RPCBVERS; /* Set the version */
 981  841                  CLNT_CONTROL(client, CLSET_VERS, (char *)&vers);
 982  842                  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);
      843 +                    (xdrproc_t)xdr_rpcb, (char *)&parms,
      844 +                    (xdrproc_t)xdr_wrapstring, (char *)&ua, *tp);
      845 +                switch (clnt_st) {
      846 +                case RPC_SUCCESS: /* Call succeeded */
      847 +                        if (ua != NULL) {
      848 +                                if (ua[0] != '\0') {
      849 +                                        address = uaddr2taddr(nconf, ua);
      850 +                                }
      851 +                                xdr_free((xdrproc_t)xdr_wrapstring,
      852 +                                    (char *)&ua);
 990  853  
 991      -                                /* address unknown */
      854 +                                if (address != NULL) {
      855 +                                        goto done;
      856 +                                }
      857 +                                /* We don't know about your universal addr */
 992  858                                  rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
 993  859                                  goto error;
 994  860                          }
 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");
1001      -#endif
1002      -                        xdr_free((xdrproc_t)xdr_wrapstring, (char *)&ua);
      861 +                        /* Try the next version */
      862 +                        break;
      863 +                case RPC_PROGVERSMISMATCH: /* RPC protocol mismatch */
      864 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      865 +                        if (rpc_createerr.cf_error.re_vers.low > vers)
      866 +                                goto error;  /* a new version, can't handle */
      867 +                        /* Try the next version */
      868 +                        break;
      869 +                case RPC_PROCUNAVAIL: /* Procedure unavailable */
      870 +                case RPC_PROGUNAVAIL: /* Program not available */
      871 +                case RPC_TIMEDOUT: /* Call timed out */
      872 +                        /* Try the next version */
      873 +                        break;
      874 +                default:
      875 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      876 +                        rpc_createerr.cf_stat = RPC_PMAPFAILURE;
      877 +                        goto error;
      878 +                        break;
      879 +                }
      880 +        } /* End of version 3 */
1003  881  
1004      -                        if (!address) {
1005      -                                /* We don't know about your universal address */
1006      -                                rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE;
      882 +        /*
      883 +         * Try version 2
      884 +         */
      885 +
      886 +#ifdef PORTMAP
      887 +        /* Try version 2 for TCP or UDP */
      888 +        if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
      889 +                ushort_t port = 0;
      890 +                struct netbuf remote;
      891 +                uint_t pmapvers = 2;
      892 +                struct pmap pmapparms;
      893 +
      894 +                /*
      895 +                 * Try UDP only - there are some portmappers out
      896 +                 * there that use UDP only.
      897 +                 */
      898 +                if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
      899 +                        struct netconfig *newnconf;
      900 +
      901 +                        if (client) {
      902 +                                CLNT_DESTROY(client);
      903 +                                client = NULL;
      904 +                                free(parms.r_addr);
      905 +                                parms.r_addr = NULL;
      906 +                        }
      907 +                        if ((handle = __rpc_setconf("udp")) == NULL) {
      908 +                                rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
1007  909                                  goto error;
1008  910                          }
1009      -                        goto done;
      911 +
      912 +                        /*
      913 +                         * The following to reinforce that you can
      914 +                         * only request for remote address through
      915 +                         * the same transport you are requesting.
      916 +                         * ie. requesting unversial address
      917 +                         * of IPv4 has to be carried through IPv4.
      918 +                         * Can't use IPv6 to send out the request.
      919 +                         * The mergeaddr in rpcbind can't handle
      920 +                         * this.
      921 +                         */
      922 +                        for (;;) {
      923 +                                if ((newnconf = __rpc_getconf(handle))
      924 +                                    == NULL) {
      925 +                                        __rpc_endconf(handle);
      926 +                                        rpc_createerr.cf_stat =
      927 +                                            RPC_UNKNOWNPROTO;
      928 +                                        goto error;
      929 +                                }
      930 +                                /*
      931 +                                 * here check the protocol family to
      932 +                                 * be consistent with the request one
      933 +                                 */
      934 +                                if (strcmp(newnconf->nc_protofmly,
      935 +                                    nconf->nc_protofmly) == NULL)
      936 +                                        break;
      937 +                        }
      938 +
      939 +                        client = _getclnthandle_timed(host, newnconf,
      940 +                            &parms.r_addr, tp);
      941 +                        __rpc_endconf(handle);
      942 +                        tmp_client = TRUE;
1010  943                  }
1011      -                if (clnt_st == RPC_PROGVERSMISMATCH) {
1012      -                        struct rpc_err rpcerr;
      944 +                if (client == NULL)
      945 +                        rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
      946 +                        tmp_client = FALSE;
      947 +                        goto error;
1013  948  
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 */
      949 +                /*
      950 +                 * Set version and retry timeout.
      951 +                 */
      952 +                CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime);
      953 +                CLNT_CONTROL(client, CLSET_VERS, (char *)&pmapvers);
      954 +
      955 +                pmapparms.pm_prog = program;
      956 +                pmapparms.pm_vers = version;
      957 +                pmapparms.pm_prot = strcmp(nconf->nc_proto, NC_TCP) ?
      958 +                    IPPROTO_UDP : IPPROTO_TCP;
      959 +                pmapparms.pm_port = 0;  /* not needed */
      960 +                clnt_st = CLNT_CALL(client, PMAPPROC_GETPORT,
      961 +                    (xdrproc_t)xdr_pmap, (caddr_t)&pmapparms,
      962 +                    (xdrproc_t)xdr_u_short, (caddr_t)&port, *tp);
      963 +                if (clnt_st != RPC_SUCCESS) {
      964 +                        rpc_createerr.cf_stat = RPC_PMAPFAILURE;
      965 +                        clnt_geterr(client, &rpc_createerr.cf_error);
1019  966                          goto error;
      967 +                } else if (port == 0) {
      968 +                        rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
      969 +                        goto error;
1020  970                  }
      971 +                port = htons(port);
      972 +                CLNT_CONTROL(client, CLGET_SVC_ADDR, (char *)&remote);
      973 +                if (((address = malloc(sizeof (struct netbuf))) == NULL) ||
      974 +                    ((address->buf = malloc(remote.len)) == NULL)) {
      975 +                        rpc_createerr.cf_stat = RPC_SYSTEMERROR;
      976 +                        clnt_geterr(client, &rpc_createerr.cf_error);
      977 +                        if (address != NULL) {
      978 +                                free(address);
      979 +                                address = NULL;
      980 +                        }
      981 +                        goto error;
      982 +                }
      983 +                (void) memcpy(address->buf, remote.buf, remote.len);
      984 +                (void) memcpy(&address->buf[sizeof (short)], &port,
      985 +                    sizeof (short));
      986 +                address->len = address->maxlen = remote.len;
      987 +                goto done;
1021  988          }
      989 +#endif
1022  990  
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  991  error:
      992 +        /* Return NULL address and NULL client */
      993 +        address = NULL;
1029  994          if (client) {
1030  995                  CLNT_DESTROY(client);
1031  996                  client = NULL;
1032  997          }
      998 +
1033  999  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      -                }
     1000 +        /* Return an address and optional client */
     1001 +        if (client != NULL && tmp_client) {
     1002 +                /* This client is the temporary one */
     1003 +                CLNT_DESTROY(client);
     1004 +                client = NULL;
1040 1005          }
1041 1006          if (clpp) {
1042 1007                  *clpp = client;
1043 1008          } else if (client) {
1044 1009                  CLNT_DESTROY(client);
1045 1010          }
1046 1011          if (parms.r_addr)
1047 1012                  free(parms.r_addr);
1048 1013          return (address);
1049 1014  }
↓ open down ↓ 38 lines elided ↑ open up ↑
1088 1053   */
1089 1054  rpcblist *
1090 1055  rpcb_getmaps(const struct netconfig *nconf, const char *host)
1091 1056  {
1092 1057          rpcblist_ptr head = NULL;
1093 1058          CLIENT *client;
1094 1059          enum clnt_stat clnt_st;
1095 1060          int vers = 0;
1096 1061  
1097 1062          client = getclnthandle((char *)host,
1098      -                        (struct netconfig *)nconf, NULL);
     1063 +            (struct netconfig *)nconf, NULL);
1099 1064          if (client == NULL)
1100 1065                  return (NULL);
1101 1066  
1102 1067          clnt_st = CLNT_CALL(client, RPCBPROC_DUMP,
1103      -                        (xdrproc_t)xdr_void, NULL,
1104      -                        (xdrproc_t)xdr_rpcblist_ptr,
1105      -                        (char *)&head, tottimeout);
     1068 +            (xdrproc_t)xdr_void, NULL,
     1069 +            (xdrproc_t)xdr_rpcblist_ptr,
     1070 +            (char *)&head, tottimeout);
1106 1071          if (clnt_st == RPC_SUCCESS)
1107 1072                  goto done;
1108 1073  
1109 1074          if ((clnt_st != RPC_PROGVERSMISMATCH) &&
1110      -                    (clnt_st != RPC_PROGUNAVAIL)) {
     1075 +            (clnt_st != RPC_PROGUNAVAIL)) {
1111 1076                  rpc_createerr.cf_stat = RPC_RPCBFAILURE;
1112 1077                  clnt_geterr(client, &rpc_createerr.cf_error);
1113 1078                  goto done;
1114 1079          }
1115 1080  
1116 1081          /* fall back to earlier version */
1117 1082          CLNT_CONTROL(client, CLGET_VERS, (char *)&vers);
1118 1083          if (vers == RPCBVERS4) {
1119 1084                  vers = RPCBVERS;
1120 1085                  CLNT_CONTROL(client, CLSET_VERS, (char *)&vers);
1121 1086                  if (CLNT_CALL(client, RPCBPROC_DUMP,
1122      -                        (xdrproc_t)xdr_void,
1123      -                        NULL, (xdrproc_t)xdr_rpcblist_ptr,
1124      -                        (char *)&head, tottimeout) == RPC_SUCCESS)
     1087 +                    (xdrproc_t)xdr_void,
     1088 +                    NULL, (xdrproc_t)xdr_rpcblist_ptr,
     1089 +                    (char *)&head, tottimeout) == RPC_SUCCESS)
1125 1090                                  goto done;
1126 1091          }
1127 1092          rpc_createerr.cf_stat = RPC_RPCBFAILURE;
1128 1093          clnt_geterr(client, &rpc_createerr.cf_error);
1129 1094  
1130 1095  done:
1131 1096          CLNT_DESTROY(client);
1132 1097          return (head);
1133 1098  }
1134 1099  
↓ open down ↓ 25 lines elided ↑ open up ↑
1160 1125          a.proc = proc;
1161 1126          a.args.args_val = argsp;
1162 1127          a.xdr_args = xdrargs;
1163 1128          r.addr = NULL;
1164 1129          r.results.results_val = resp;
1165 1130          r.xdr_res = xdrres;
1166 1131  
1167 1132          for (rpcb_vers = RPCBVERS4; rpcb_vers >= RPCBVERS; rpcb_vers--) {
1168 1133                  CLNT_CONTROL(client, CLSET_VERS, (char *)&rpcb_vers);
1169 1134                  stat = CLNT_CALL(client, RPCBPROC_CALLIT,
1170      -                        (xdrproc_t)xdr_rpcb_rmtcallargs, (char *)&a,
1171      -                        (xdrproc_t)xdr_rpcb_rmtcallres, (char *)&r, tout);
     1135 +                    (xdrproc_t)xdr_rpcb_rmtcallargs, (char *)&a,
     1136 +                    (xdrproc_t)xdr_rpcb_rmtcallres, (char *)&r, tout);
1172 1137                  if ((stat == RPC_SUCCESS) && (addr_ptr != NULL)) {
1173 1138                          struct netbuf *na;
1174 1139  
1175 1140                          na = uaddr2taddr((struct netconfig *)nconf, r.addr);
1176 1141                          if (!na) {
1177 1142                                  stat = RPC_N2AXLATEFAILURE;
1178 1143                                  ((struct netbuf *)addr_ptr)->len = 0;
1179 1144                                  goto error;
1180 1145                          }
1181 1146                          if (na->len > addr_ptr->maxlen) {
↓ open down ↓ 2 lines elided ↑ open up ↑
1184 1149                                  netdir_free((char *)na, ND_ADDR);
1185 1150                                  ((struct netbuf *)addr_ptr)->len = 0;
1186 1151                                  goto error;
1187 1152                          }
1188 1153                          (void) memcpy(addr_ptr->buf, na->buf, (int)na->len);
1189 1154                          ((struct netbuf *)addr_ptr)->len = na->len;
1190 1155                          netdir_free((char *)na, ND_ADDR);
1191 1156                          break;
1192 1157                  }
1193 1158                  if ((stat != RPC_PROGVERSMISMATCH) &&
1194      -                            (stat != RPC_PROGUNAVAIL))
     1159 +                    (stat != RPC_PROGUNAVAIL))
1195 1160                          goto error;
1196 1161          }
1197 1162  error:
1198 1163          CLNT_DESTROY(client);
1199 1164          if (r.addr)
1200 1165                  xdr_free((xdrproc_t)xdr_wrapstring, (char *)&r.addr);
1201 1166          return (stat);
1202 1167  }
1203 1168  
1204 1169  /*
↓ open down ↓ 27 lines elided ↑ open up ↑
1232 1197                  }
1233 1198                  client = getclnthandle((char *)host, nconf, NULL);
1234 1199                  if (client)
1235 1200                          break;
1236 1201          }
1237 1202          __rpc_endconf(handle);
1238 1203          if (client == NULL)
1239 1204                  return (FALSE);
1240 1205  
1241 1206          st = CLNT_CALL(client, RPCBPROC_GETTIME,
1242      -                (xdrproc_t)xdr_void, NULL,
1243      -                (xdrproc_t)xdr_time_t, (char *)timep, tottimeout);
     1207 +            (xdrproc_t)xdr_void, NULL,
     1208 +            (xdrproc_t)xdr_time_t, (char *)timep, tottimeout);
1244 1209  
1245 1210          if ((st == RPC_PROGVERSMISMATCH) || (st == RPC_PROGUNAVAIL)) {
1246 1211                  CLNT_CONTROL(client, CLGET_VERS, (char *)&vers);
1247 1212                  if (vers == RPCBVERS4) {
1248 1213                          /* fall back to earlier version */
1249 1214                          vers = RPCBVERS;
1250 1215                          CLNT_CONTROL(client, CLSET_VERS, (char *)&vers);
1251 1216                          st = CLNT_CALL(client, RPCBPROC_GETTIME,
1252      -                                (xdrproc_t)xdr_void, NULL,
1253      -                                (xdrproc_t)xdr_time_t, (char *)timep,
1254      -                                tottimeout);
     1217 +                            (xdrproc_t)xdr_void, NULL,
     1218 +                            (xdrproc_t)xdr_time_t, (char *)timep,
     1219 +                            tottimeout);
1255 1220                  }
1256 1221          }
1257 1222          CLNT_DESTROY(client);
1258 1223          return (st == RPC_SUCCESS? TRUE : FALSE);
1259 1224  }
1260 1225  
1261 1226  /*
1262 1227   * Converts taddr to universal address.  This routine should never
1263 1228   * really be called because local n2a libraries are always provided.
1264 1229   */
↓ open down ↓ 10 lines elided ↑ open up ↑
1275 1240          }
1276 1241          if (taddr == NULL) {
1277 1242                  rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
1278 1243                  return (NULL);
1279 1244          }
1280 1245          client = local_rpcb();
1281 1246          if (!client)
1282 1247                  return (NULL);
1283 1248  
1284 1249          CLNT_CALL(client, RPCBPROC_TADDR2UADDR, (xdrproc_t)xdr_netbuf,
1285      -                (char *)taddr, (xdrproc_t)xdr_wrapstring, (char *)&uaddr,
1286      -                tottimeout);
     1250 +            (char *)taddr, (xdrproc_t)xdr_wrapstring, (char *)&uaddr,
     1251 +            tottimeout);
1287 1252          CLNT_DESTROY(client);
1288 1253          return (uaddr);
1289 1254  }
1290 1255  
1291 1256  /*
1292 1257   * Converts universal address to netbuf.  This routine should never
1293 1258   * really be called because local n2a libraries are always provided.
1294 1259   */
1295 1260  struct netbuf *
1296 1261  rpcb_uaddr2taddr(struct netconfig *nconf, char *uaddr)
↓ open down ↓ 14 lines elided ↑ open up ↑
1311 1276          if (!client)
1312 1277                  return (NULL);
1313 1278  
1314 1279          taddr = calloc(1, sizeof (struct netbuf));
1315 1280          if (taddr == NULL) {
1316 1281                  CLNT_DESTROY(client);
1317 1282                  return (NULL);
1318 1283          }
1319 1284  
1320 1285          if (CLNT_CALL(client, RPCBPROC_UADDR2TADDR, (xdrproc_t)xdr_wrapstring,
1321      -                (char *)&uaddr, (xdrproc_t)xdr_netbuf, (char *)taddr,
1322      -                tottimeout) != RPC_SUCCESS) {
     1286 +            (char *)&uaddr, (xdrproc_t)xdr_netbuf, (char *)taddr,
     1287 +            tottimeout) != RPC_SUCCESS) {
1323 1288                  free(taddr);
1324 1289                  taddr = NULL;
1325 1290          }
1326 1291          CLNT_DESTROY(client);
1327 1292          return (taddr);
1328 1293  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX