1    	/*
2    	 * Copyright (c) 2010, Oracle America, Inc.
3    	 * Copyright (c) 2012-2018 Red Hat, Inc. and/or its affiliates.
4    	 * All rights reserved.
5    	 *
6    	 * Redistribution and use in source and binary forms, with or without
7    	 * modification, are permitted provided that the following conditions are met:
8    	 * - Redistributions of source code must retain the above copyright notice,
9    	 *   this list of conditions and the following disclaimer.
10   	 * - Redistributions in binary form must reproduce the above copyright notice,
11   	 *   this list of conditions and the following disclaimer in the documentation
12   	 *   and/or other materials provided with the distribution.
13   	 * - Neither the name of the "Oracle America, Inc." nor the names of its
14   	 *   contributors may be used to endorse or promote products derived
15   	 *   from this software without specific prior written permission.
16   	 *
17   	 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18   	 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19   	 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20   	 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21   	 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22   	 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23   	 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24   	 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25   	 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26   	 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27   	 * POSSIBILITY OF SUCH DAMAGE.
28   	 */
29   	
30   	/*
31   	 * rpcb_clnt.c
32   	 * interface to rpcbind rpc service.
33   	 */
34   	#include "config.h"
35   	#include <pthread.h>
36   	#include <reentrant.h>
37   	#include <sys/stat.h>
38   	#include <sys/types.h>
39   	#include <sys/socket.h>
40   	#include <sys/un.h>
41   	#include <sys/utsname.h>
42   	#include <rpc/rpc.h>
43   	#include <rpc/xdr_inline.h>
44   	#include <rpc/rpcb_prot.h>
45   	#include <rpc/nettype.h>
46   	#include <netconfig.h>
47   	#ifdef PORTMAP
48   	#include <netinet/in.h>		/* FOR IPPROTO_TCP/UDP definitions */
49   	#include <rpc/pmap_prot.h>
50   	#endif				/* PORTMAP */
51   	#include <stdio.h>
52   	#include <errno.h>
53   	#include <stdlib.h>
54   	#include <string.h>
55   	#include <unistd.h>
56   	#include <netdb.h>
57   	#include <syslog.h>
58   	#include <assert.h>
59   	
60   	#include "rpc_com.h"
61   	#include "strl.h"
62   	
63   	/* retry timeout default to the moon and back */
64   	static struct timespec to = { 3, 0 };
65   	
66   	extern bool xdr_wrapstring(XDR *, char **);
67   	
68   	static const char nullstring[] = "\000";
69   	
70   	#define RPCB_OWNER_STRING "libntirpc"
71   	
72   	#define CACHESIZE 6
73   	
74   	struct address_cache {
75   		char *ac_host;
76   		char *ac_netid;
77   		char *ac_uaddr;
78   		struct netbuf *ac_taddr;
79   		struct address_cache *ac_next;
80   	};
81   	
82   	static struct address_cache *front;
83   	static int cachesize;
84   	
85   	#define CLCR_GET_RPCB_TIMEOUT 1
86   	#define CLCR_SET_RPCB_TIMEOUT 2
87   	
88   	extern int __rpc_lowvers;
89   	
90   	static struct address_cache *check_cache(const char *, const char *);
91   	static void delete_cache(struct netbuf *);
92   	static void add_cache(const char *, const char *, struct netbuf *, char *);
93   	static CLIENT *getclnthandle(const char *, const struct netconfig *, char **);
94   	static CLIENT *local_rpcb(const char *);
95   	#ifdef NOTUSED
96   	static struct netbuf *got_entry(rpcb_entry_list_ptr, const struct netconfig *);
97   	#endif
98   	
99   	/*
100  	 * This routine adjusts the timeout used for calls to the remote rpcbind.
101  	 * Also, this routine can be used to set the use of portmapper version 2
102  	 * only when doing rpc_broadcasts
103  	 * These are private routines that may not be provided in future releases.
104  	 */
105  	bool __rpc_control(int request, void *info)
106  	{
107  		switch (request) {
108  		case CLCR_GET_RPCB_TIMEOUT:
109  			*(struct timespec *)info = to;
110  			break;
111  		case CLCR_SET_RPCB_TIMEOUT:
112  			to = *(struct timespec *)info;
113  			break;
114  		case CLCR_SET_LOWVERS:
115  			__rpc_lowvers = *(int *)info;
116  			break;
117  		case CLCR_GET_LOWVERS:
118  			*(int *)info = __rpc_lowvers;
119  			break;
120  		default:
121  			return (false);
122  		}
123  		return (true);
124  	}
125  	
126  	/*
127  	 * It might seem that a reader/writer lock would be more reasonable here.
128  	 * However because getclnthandle(), the only user of the cache functions,
129  	 * may do a delete_cache() operation if a check_cache() fails to return an
130  	 * address useful to clnt_tli_ncreate(), we may as well use a mutex.
131  	 */
132  	/*
133  	 * As it turns out, if the cache lock is *not* a reader/writer lock, we will
134  	 * block all clnt_ncreate's if we are trying to connect to a host that's down,
135  	 * since the lock will be held all during that time.
136  	 */
137  	extern rwlock_t rpcbaddr_cache_lock;
138  	
139  	/*
140  	 * The routines check_cache(), add_cache(), delete_cache() manage the
141  	 * cache of rpcbind addresses for (host, netid).
142  	 */
143  	
144  	static struct address_cache *
145  	check_cache(const char *host, const char *netid)
146  	{
147  		struct address_cache *cptr;
148  	
149  		/* READ LOCK HELD ON ENTRY: rpcbaddr_cache_lock */
150  		for (cptr = front; cptr != NULL; cptr = cptr->ac_next) {
151  			if (!strcmp(cptr->ac_host, host)
152  			    && !strcmp(cptr->ac_netid, netid)) {
153  	#ifdef ND_DEBUG
154  				fprintf(stderr, "Found cache entry for %s: %s\n", host,
155  					netid);
156  	#endif
157  				return (cptr);
158  			}
159  		}
160  		return ((struct address_cache *)NULL);
161  	}
162  	
163  	static void
164  	delete_cache(struct netbuf *addr)
165  	{
166  		struct address_cache *cptr, *prevptr = NULL;
167  	
168  		/* WRITE LOCK HELD ON ENTRY: rpcbaddr_cache_lock */
169  		for (cptr = front; cptr != NULL; cptr = cptr->ac_next) {
170  			if (!memcmp(cptr->ac_taddr->buf, addr->buf, addr->len)) {
171  				mem_free(cptr->ac_host, 0);	/* XXX */
172  				mem_free(cptr->ac_netid, 0);
173  				mem_free(cptr->ac_taddr->buf, cptr->ac_taddr->len);
174  				mem_free(cptr->ac_taddr, sizeof(struct netbuf));
175  				if (cptr->ac_uaddr)
176  					mem_free(cptr->ac_uaddr, 0);
177  				if (prevptr)
178  					prevptr->ac_next = cptr->ac_next;
179  				else
180  					front = cptr->ac_next;
181  				mem_free(cptr, sizeof(struct address_cache));
182  				cachesize--;
183  				break;
184  			}
185  			prevptr = cptr;
186  		}
187  	}
188  	
189  	static void
190  	add_cache(const char *host, const char *netid, struct netbuf *taddr,
191  		  char *uaddr)
192  	{
193  		struct address_cache *ad_cache, *cptr, *prevptr;
194  	
195  		if (!host) {
196  			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: missing host", __func__);
197  			return;
198  		}
199  		ad_cache = (struct address_cache *)mem_zalloc(sizeof(*ad_cache));
200  	
201  		ad_cache->ac_host = mem_strdup(host);
202  		ad_cache->ac_netid = mem_strdup(netid);
203  		ad_cache->ac_uaddr = uaddr ? mem_strdup(uaddr) : NULL;
204  		ad_cache->ac_taddr = (struct netbuf *)mem_zalloc(sizeof(struct netbuf));
205  		ad_cache->ac_taddr->len = ad_cache->ac_taddr->maxlen = taddr->len;
206  		ad_cache->ac_taddr->buf = (char *)mem_zalloc(taddr->len);
207  		memcpy(ad_cache->ac_taddr->buf, taddr->buf, taddr->len);
208  	#ifdef ND_DEBUG
209  		fprintf(stderr, "Added to cache: %s : %s\n", host, netid);
210  	#endif
211  	
212  		/* VARIABLES PROTECTED BY rpcbaddr_cache_lock:  cptr */
213  		rwlock_wrlock(&rpcbaddr_cache_lock);
214  		if (cachesize < CACHESIZE) {
215  			ad_cache->ac_next = front;
216  			front = ad_cache;
217  			cachesize++;
218  		} else {
219  			/* Free the last entry */
220  			cptr = front;
221  			prevptr = NULL;
222  			while (cptr->ac_next) {
223  				prevptr = cptr;
224  				cptr = cptr->ac_next;
225  			}
226  	
227  	#ifdef ND_DEBUG
228  			fprintf(stderr, "Deleted from cache: %s : %s\n", cptr->ac_host,
229  				cptr->ac_netid);
230  	#endif
231  			mem_free(cptr->ac_host, 0);	/* XXX */
232  			mem_free(cptr->ac_netid, 0);
233  			mem_free(cptr->ac_taddr->buf, cptr->ac_taddr->len);
234  			mem_free(cptr->ac_taddr, sizeof(struct netbuf));
235  			if (cptr->ac_uaddr)
236  				mem_free(cptr->ac_uaddr, 0);
237  	
238  			if (prevptr) {
239  				prevptr->ac_next = NULL;
240  				ad_cache->ac_next = front;
241  				front = ad_cache;
242  			} else {
243  				front = ad_cache;
244  				ad_cache->ac_next = NULL;
245  			}
246  			mem_free(cptr, sizeof(struct address_cache));
247  		}
248  		rwlock_unlock(&rpcbaddr_cache_lock);
249  		return;
250  	}
251  	
252  	/*
253  	 * This routine will return a client handle that is connected to the
254  	 * rpcbind. If targaddr is non-NULL, the "universal address" of the
255  	 * host will be stored in *targaddr; the caller is responsible for
256  	 * freeing this string.
257  	 * On error, a CLIENT with cl_error.re_status set
258  	 */
259  	static CLIENT *getclnthandle(const char *host, const struct netconfig *nconf,
260  				     char **targaddr)
261  	{
262  		CLIENT *client;
263  		struct netbuf *addr, taddr;
264  		struct netbuf addr_to_delete;
265  		struct __rpc_sockinfo si;
266  		struct addrinfo hints, *res, *tres;
267  		struct address_cache *ad_cache;
268  		char *tmpaddr;
269  		char *t;
270  	
271  		memset(&addr_to_delete, '\0', sizeof(addr_to_delete));
272  	
273  	/* VARIABLES PROTECTED BY rpcbaddr_cache_lock:  ad_cache */
274  	
275  		/* Get the address of the rpcbind.  Check cache first */
276  		client = NULL;
277  		if (targaddr)
278  			*targaddr = NULL;
279  		addr_to_delete.len = 0;
280  		rwlock_rdlock(&rpcbaddr_cache_lock);
281  		ad_cache = NULL;
282  		if (host != NULL)
283  			ad_cache = check_cache(host, nconf->nc_netid);
284  		if (ad_cache != NULL) {
285  			addr = ad_cache->ac_taddr;
286  			client =
287  			    clnt_tli_ncreate(RPC_ANYFD, nconf, addr,
288  					     (rpcprog_t) RPCBPROG,
289  					     (rpcvers_t) RPCBVERS4, 0, 0);
290  			if (CLNT_SUCCESS(client)) {
291  				if (targaddr)
292  					*targaddr = mem_strdup(ad_cache->ac_uaddr);
293  				rwlock_unlock(&rpcbaddr_cache_lock);
294  				return (client);
295  			}
296  	
297  			t = rpc_sperror(&client->cl_error, __func__);
298  			__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB, "%s", t);
299  			mem_free(t, RPC_SPERROR_BUFLEN);
300  	
301  			addr_to_delete.len = addr->len;
302  			addr_to_delete.buf = (char *)mem_zalloc(addr->len);
303  			memcpy(addr_to_delete.buf, addr->buf, addr->len);
304  		}
305  		rwlock_unlock(&rpcbaddr_cache_lock);
306  		if (addr_to_delete.len != 0) {
307  			/*
308  			 * Assume this may be due to cache data being
309  			 *  outdated
310  			 */
311  			rwlock_wrlock(&rpcbaddr_cache_lock);
312  			delete_cache(&addr_to_delete);
313  			rwlock_unlock(&rpcbaddr_cache_lock);
314  			mem_free(addr_to_delete.buf, addr_to_delete.len);
315  		}
316  		if (!__rpc_nconf2sockinfo(nconf, &si)) {
317  			if (client != NULL) {
318  				/* if client!=NULL then there should
319  				 * have been a failure
320  				 */
321  				assert(CLNT_FAILURE(client));
322  				/* destroy the failed client */
323  				CLNT_DESTROY(client);
324  			}
325  	
326  			__warnx(TIRPC_DEBUG_FLAG_WARN, "%s: %s",
327  				__func__, clnt_sperrno(RPC_UNKNOWNPROTO));
328  			client = clnt_raw_ncreate(1, 1);
329  			client->cl_error.re_status = RPC_UNKNOWNPROTO;
330  			goto out_err;
331  		}
332  	
333  		memset(&hints, 0, sizeof(hints));
334  		hints.ai_family = si.si_af;
335  		hints.ai_socktype = si.si_socktype;
336  		hints.ai_protocol = si.si_proto;
337  	
338  		__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB,
339  			"%s: trying netid %s family %d proto %d socktype %d",
340  			__func__, nconf->nc_netid, si.si_af, si.si_proto,
341  			si.si_socktype);
342  	
343  		if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
344  			client = local_rpcb(__func__);
345  			if (CLNT_SUCCESS(client)) {
346  				struct sockaddr_un sun;
347  	
348  				if (targaddr) {
349  					*targaddr = mem_zalloc(sizeof(sun.sun_path));
350  					strlcpy(*targaddr, _PATH_RPCBINDSOCK,
351  						sizeof(sun.sun_path));
352  				}
353  				return (client);
354  			}
355  			goto out_err;
356  		} else {
357  			if (getaddrinfo(host, "sunrpc", &hints, &res) != 0) {
358  				if (client != NULL) {
359  					/* if client!=NULL then there should
360  					 * have been a failure
361  					 */
362  					assert(CLNT_FAILURE(client));
363  					/* destroy the failed client */
364  					CLNT_DESTROY(client);
365  				}
366  	
367  				__warnx(TIRPC_DEBUG_FLAG_WARN, "%s: %s",
368  					__func__, clnt_sperrno(RPC_UNKNOWNHOST));
369  				client = clnt_raw_ncreate(1, 1);
370  				client->cl_error.re_status = RPC_UNKNOWNHOST;
371  				goto out_err;
372  			}
373  		}
374  	
375  		for (tres = res; tres != NULL; tres = tres->ai_next) {
376  			taddr.buf = tres->ai_addr;
377  			taddr.len = taddr.maxlen = tres->ai_addrlen;
378  	
379  	#ifdef ND_DEBUG
380  			{
381  				char *ua;
382  	
383  				ua = taddr2uaddr(nconf, &taddr);
384  				fprintf(stderr, "Got it [%s]\n", ua);
385  				mem_free(ua, 0);	/* XXX */
386  			}
387  	#endif
388  	
389  	#ifdef ND_DEBUG
390  			{
391  				int i;
392  	
393  				fprintf(stderr, "\tnetbuf len = %d, maxlen = %d\n",
394  					taddr.len, taddr.maxlen);
395  				fprintf(stderr, "\tAddress is ");
396  				for (i = 0; i < taddr.len; i++)
397  					fprintf(stderr, "%u.",
398  						((char *)(taddr.buf))[i]);
399  				fprintf(stderr, "\n");
400  			}
401  	#endif
402  			client =
403  			    clnt_tli_ncreate(RPC_ANYFD, nconf, &taddr,
404  					     (rpcprog_t) RPCBPROG,
405  					     (rpcvers_t) RPCBVERS4, 0, 0);
406  			if (CLNT_SUCCESS(client)) {
407  				tmpaddr = targaddr ? taddr2uaddr(nconf, &taddr) : NULL;
408  				add_cache(host, nconf->nc_netid, &taddr, tmpaddr);
409  				if (targaddr)
410  					*targaddr = tmpaddr;
411  				break;
412  			}
413  	
414  			t = rpc_sperror(&client->cl_error, __func__);
415  			__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB, "%s", t);
416  			mem_free(t, RPC_SPERROR_BUFLEN);
417  		}
418  		if (res)
419  			freeaddrinfo(res);
420  	 out_err:
421  		if (CLNT_FAILURE(client) && targaddr)
422  			mem_free(*targaddr, 0);
423  		return (client);
424  	}
425  	
426  	/*
427  	 * Set a mapping between program, version and address.
428  	 * Calls the rpcbind service to do the mapping.
429  	 */
430  	bool
431  	rpcb_set(rpcprog_t program, rpcvers_t version, const struct netconfig *nconf,
432  		 /* Network structure of transport */
433  		 const struct netbuf *address /* Services netconfig address */)
434  	{
435  		CLIENT *client;
436  		struct clnt_req *cc;
437  		RPCB parms;
438  		char uidbuf[32];
439  		enum clnt_stat stat;
440  		bool_t rslt = false;	/* yes, bool_t */
441  	
442  		/* parameter checking */
443  		if (nconf == NULL) {
444  			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %s",
445  				__func__, clnt_sperrno(RPC_UNKNOWNPROTO));
446  			return (false);
447  		}
448  		if (address == NULL) {
449  			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %s",
450  				__func__, clnt_sperrno(RPC_UNKNOWNADDR));
451  			return (false);
452  		}
453  		client = local_rpcb(__func__);
454  		if (CLNT_FAILURE(client)) {
455  			CLNT_DESTROY(client);
456  			return (false);
457  		}
458  	
459  		/* convert to universal */
460  		/*LINTED const castaway */
461  		parms.r_addr =
462  		    taddr2uaddr((struct netconfig *)nconf, (struct netbuf *)address);
463  		if (!parms.r_addr) {
464  			CLNT_DESTROY(client);
465  			__warnx(TIRPC_DEBUG_FLAG_WARN, "%s: %s",
466  				__func__, clnt_sperrno(RPC_N2AXLATEFAILURE));
467  			return (false);	/* no universal address */
468  		}
469  		parms.r_prog = program;
470  		parms.r_vers = version;
471  		parms.r_netid = nconf->nc_netid;
472  		/*
473  		 * Though uid is not being used directly, we still send it for
474  		 * completeness.  For non-unix platforms, perhaps some other
475  		 * string or an empty string can be sent.
476  		 */
477  		(void)snprintf(uidbuf, sizeof(uidbuf), "%d", geteuid());
478  		parms.r_owner = uidbuf;
479  	
480  		cc = mem_alloc(sizeof(*cc));
481  		clnt_req_fill(cc, client, authnone_ncreate(), RPCBPROC_SET,
482  			      (xdrproc_t) xdr_rpcb, &parms,
483  			      (xdrproc_t) xdr_bool, &rslt);
484  		stat = clnt_req_setup(cc, to);
485  		if (stat == RPC_SUCCESS) {
486  			stat = CLNT_CALL_WAIT(cc);
487  		}
488  		if (stat != RPC_SUCCESS) {
489  			char *t = rpc_sperror(&cc->cc_error, __func__);
490  	
491  			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s", t);
492  			mem_free(t, RPC_SPERROR_BUFLEN);
493  		}
494  	
495  		clnt_req_release(cc);
496  		CLNT_DESTROY(client);
497  		mem_free(parms.r_addr, 0);
498  		return (rslt);
499  	}
500  	
501  	/*
502  	 * Remove the mapping between program, version and netbuf address.
503  	 * Calls the rpcbind service to do the un-mapping.
504  	 * If netbuf is NULL, unset for all the transports, otherwise unset
505  	 * only for the given transport.
506  	 */
507  	bool
508  	rpcb_unset(rpcprog_t program, rpcvers_t version,
509  		   const struct netconfig *nconf)
510  	{
511  		CLIENT *client;
512  		struct clnt_req *cc;
513  		RPCB parms;
514  		char uidbuf[32];
515  		enum clnt_stat stat;
516  		bool_t rslt = false;	/* yes, bool_t */
517  	
518  		client = local_rpcb(__func__);
519  		if (CLNT_FAILURE(client)) {
520  			CLNT_DESTROY(client);
521  			return (false);
522  		}
523  	
524  		parms.r_prog = program;
525  		parms.r_vers = version;
526  		if (nconf)
527  			parms.r_netid = nconf->nc_netid;
528  		else {
529  			/*LINTED const castaway */
530  			parms.r_netid = (char *)&nullstring[0];	/* unsets  all */
531  		}
532  		/*LINTED const castaway */
533  		parms.r_addr = (char *)&nullstring[0];
534  		(void)snprintf(uidbuf, sizeof(uidbuf), "%d", geteuid());
535  		parms.r_owner = uidbuf;
536  	
537  		cc = mem_alloc(sizeof(*cc));
538  		clnt_req_fill(cc, client, authnone_ncreate(), RPCBPROC_UNSET,
539  			      (xdrproc_t) xdr_rpcb, &parms,
540  			      (xdrproc_t) xdr_bool, &rslt);
541  		stat = clnt_req_setup(cc, to);
542  		if (stat == RPC_SUCCESS) {
543  			stat = CLNT_CALL_WAIT(cc);
544  		}
545  		if (stat != RPC_SUCCESS) {
546  			char *t = rpc_sperror(&cc->cc_error, __func__);
547  	
548  			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s", t);
549  			mem_free(t, RPC_SPERROR_BUFLEN);
550  		}
551  	
552  		clnt_req_release(cc);
553  		CLNT_DESTROY(client);
554  		return (rslt);
555  	}
556  	
557  	#ifdef NOTUSED
558  	/*
559  	 * From the merged list, find the appropriate entry
560  	 */
561  	static struct netbuf *
562  	got_entry(rpcb_entry_list_ptr relp,
563  		  const struct netconfig *nconf)
564  	{
565  		struct netbuf *na = NULL;
566  		rpcb_entry_list_ptr sp;
567  		rpcb_entry *rmap;
568  	
569  		for (sp = relp; sp != NULL; sp = sp->rpcb_entry_next) {
570  			rmap = &sp->rpcb_entry_map;
571  			if ((strcmp(nconf->nc_proto, rmap->r_nc_proto) == 0)
572  			    && (strcmp(nconf->nc_protofmly, rmap->r_nc_protofmly) == 0)
573  			    && (nconf->nc_semantics == rmap->r_nc_semantics)
574  			    && (rmap->r_maddr != NULL) && (rmap->r_maddr[0] != 0)) {
575  				na = uaddr2taddr(nconf, rmap->r_maddr);
576  				if (!na)
577  					__warnx(TIRPC_DEBUG_FLAG_WARN, "%s: %s",
578  						__func__,
579  						clnt_sperrno(RPC_N2AXLATEFAILURE));
580  				break;
581  			}
582  		}
583  		return (na);
584  	}
585  	#endif
586  	
587  	/*
588  	 * Quick check to see if rpcbind is up.  Tries to connect over
589  	 * local transport.
590  	 */
591  	bool
592  	__rpcbind_is_up(void)
593  	{
594  		struct netconfig *nconf;
595  		struct sockaddr_un sun;
596  		void *localhandle;
597  		int sock;
598  	
599  		nconf = NULL;
600  		localhandle = setnetconfig();
601  		if (localhandle == NULL)
602  			return (false);
603  	
604  		while ((nconf = getnetconfig(localhandle)) != NULL) {
605  			if (nconf->nc_protofmly != NULL
606  			    && strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0)
607  				break;
608  		}
609  		endnetconfig(localhandle);
610  		if (nconf == NULL)
611  			return (false);
612  	
613  		memset(&sun, 0, sizeof(sun));
614  		sock = socket(AF_LOCAL, SOCK_STREAM, 0);
615  		if (sock < 0)
616  			return (false);
617  		sun.sun_family = AF_LOCAL;
618  		strlcpy(sun.sun_path, _PATH_RPCBINDSOCK, sizeof(sun.sun_path));
619  	
620  		if (connect(sock, (struct sockaddr *)&sun, sizeof(sun)) < 0) {
621  			close(sock);
622  			return (false);
623  		}
624  	
625  		close(sock);
626  		return (true);
627  	}
628  	
629  	/*
630  	 * An internal function which optimizes rpcb_getaddr function.  It also
631  	 * returns the client handle that it uses to contact the remote rpcbind.
632  	 *
633  	 * The algorithm used: If the transports is TCP or UDP, it first tries
634  	 * version 2 (portmap), 4 and then 3 (svr4).  This order should be
635  	 * changed in the next OS release to 4, 2 and 3.  We are assuming that by
636  	 * that time, version 4 would be available on many machines on the network.
637  	 * With this algorithm, we get performance as well as a plan for
638  	 * obsoleting version 2.
639  	 *
640  	 * For all other transports, the algorithm remains as 4 and then 3.
641  	 *
642  	 * XXX: Due to some problems with t_connect(), we do not reuse the same client
643  	 * handle for COTS cases and hence in these cases we do not return the
644  	 * client handle.  This code will change if t_connect() ever
645  	 * starts working properly.  Also look under clnt_vc.c.
646  	 */
647  	struct netbuf *
648  	__rpcb_findaddr_timed(rpcprog_t program, rpcvers_t version,
649  			      const struct netconfig *nconf,
650  			      const char *host, CLIENT **clpp,
651  			      struct timeval *tp)
652  	{
653  		char *ua = NULL;
(1) Event assignment: Assigning: "address" = "NULL".
Also see events: [null][dead_error_condition][dead_error_line]
654  		struct netbuf *address = NULL;
655  		CLIENT *client = NULL;
656  		struct clnt_req *cc;
657  		char *t;
658  		AUTH *auth;
659  		RPCB parms;
660  		struct netbuf servaddr;
661  		struct timespec tv;
662  		rpcvers_t vers;
663  		rpcvers_t start_vers = RPCBVERS4;
664  		enum clnt_stat clnt_st;
665  	
666  		parms.r_addr = NULL;
667  	
668  		/* parameter checking */
669  		if (nconf == NULL) {
670  			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %s",
671  				__func__, clnt_sperrno(RPC_UNKNOWNPROTO));
672  			client = clnt_raw_ncreate(program, version);
673  			client->cl_error.re_status = RPC_UNKNOWNPROTO;
674  			goto done;
675  		}
676  	
677  		/* authnone handle */
678  		auth = authnone_ncreate();	/* idempotent */
679  	
680  		/*
681  		 * Use default total timeout if no timeout is specified.
682  		 */
683  		if (tp == NULL)
684  			tv = to;
685  		else {
686  			tv.tv_sec = tp->tv_sec;
687  			tv.tv_nsec = tp->tv_usec * 1000;
688  		}
689  	
690  	#ifdef PORTMAP
691  		/* Try version 2 for TCP or UDP */
692  		if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
693  			struct netbuf remote;
694  			struct pmap pmapparms;
695  			rpcvers_t pmapvers = 2;
696  			uint16_t port = 0;
697  	
698  			if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
699  				client = getclnthandle(host, nconf, &parms.r_addr);
700  			} else if (strcmp(nconf->nc_proto, NC_UDP) == 0)
701  				client = getclnthandle(host, nconf, &parms.r_addr);
702  			else
703  				goto try_rpcbind;
704  			if (CLNT_FAILURE(client))
705  				goto error;
706  	
707  			CLNT_CONTROL(client, CLSET_VERS, (char *)&pmapvers);
708  	
709  			pmapparms.pm_prog = program;
710  			pmapparms.pm_vers = version;
711  			pmapparms.pm_prot =
712  			    strcmp(nconf->nc_proto, NC_TCP) ? IPPROTO_UDP : IPPROTO_TCP;
713  			pmapparms.pm_port = 0;	/* not needed */
714  	
715  			cc = mem_alloc(sizeof(*cc));
716  			clnt_req_fill(cc, client, auth, PMAPPROC_GETPORT,
717  				      (xdrproc_t) xdr_pmap, &pmapparms,
718  				      (xdrproc_t) xdr_uint16_t, &port);
719  			clnt_st = clnt_req_setup(cc, tv);
720  			if (clnt_st == RPC_SUCCESS) {
721  				clnt_st = CLNT_CALL_WAIT(cc);
722  			}
723  			if (clnt_st != RPC_SUCCESS) {
724  				if ((clnt_st == RPC_PROGVERSMISMATCH)
725  				    || (clnt_st == RPC_PROGUNAVAIL)) {
726  					clnt_req_release(cc);
727  					goto try_rpcbind;
728  				}
729  				client->cl_error = cc->cc_error;
730  				clnt_req_release(cc);
731  				goto error;
732  			}
733  			clnt_req_release(cc);
734  	
735  			if (port == 0) {
736  				address = NULL;
737  				client->cl_error.re_status = RPC_PROGNOTREGISTERED;
738  				goto error;
739  			}
740  			port = htons(port);
741  			CLNT_CONTROL(client, CLGET_SVC_ADDR, (char *)&remote);
742  	
743  			address = (struct netbuf *)mem_zalloc(sizeof(struct netbuf));
744  			address->buf = (char *)mem_alloc(remote.len);
745  	
746  			memcpy(address->buf, remote.buf, remote.len);
747  			memcpy(&((char *)address->buf)[sizeof(uint16_t)],
748  			       (char *)(void *)&port, sizeof(uint16_t));
749  			address->len = address->maxlen = remote.len;
750  			goto done;
751  		}
752  	
753  	 try_rpcbind:
754  	#endif				/* PORTMAP */
755  	
756  		parms.r_prog = program;
757  		parms.r_vers = version;
758  		parms.r_netid = nconf->nc_netid;
759  	
760  		/*
761  		 * rpcbind ignores the r_owner field in GETADDR requests, but we
762  		 * need to give xdr_rpcb something to gnaw on. Might as well make
763  		 * it something human readable for when we see these in captures.
764  		 */
765  		parms.r_owner = RPCB_OWNER_STRING;
766  	
767  		/* Now the same transport is to be used to get the address */
768  		if (client && ((nconf->nc_semantics == NC_TPI_COTS_ORD)
769  			       || (nconf->nc_semantics == NC_TPI_COTS))) {
770  			/* A CLTS type of client - destroy it */
771  			CLNT_DESTROY(client);
772  			client = NULL;
773  			mem_free(parms.r_addr, 0);
774  			parms.r_addr = NULL;
775  		}
776  	
777  		if (client == NULL) {
778  			client = getclnthandle(host, nconf, &parms.r_addr);
779  			if (CLNT_FAILURE(client))
780  				goto error;
781  		}
782  		if (parms.r_addr == NULL) {
783  			/*LINTED const castaway */
784  			parms.r_addr = (char *)&nullstring[0];
785  		}
786  	
787  		cc = mem_alloc(sizeof(*cc));
788  		clnt_req_fill(cc, client, auth, RPCBPROC_GETADDR,
789  			      (xdrproc_t) xdr_rpcb, &parms,
790  			      (xdrproc_t) xdr_wrapstring, &ua);
791  		/* First try from start_vers(4) and then version 3 (RPCBVERS) */
792  	
793  		for (vers = start_vers; vers >= RPCBVERS; vers--) {
794  			/* Set the version */
795  			CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&vers);
796  	
797  			clnt_st = clnt_req_setup(cc, tv);
798  			if (clnt_st == RPC_SUCCESS) {
799  				clnt_st = CLNT_CALL_WAIT(cc);
800  			}
801  			if (clnt_st == RPC_SUCCESS) {
802  				clnt_req_release(cc);
803  				if ((ua == NULL) || (ua[0] == 0)) {
804  					/* address unknown */
805  					client->cl_error.re_status =
806  								RPC_PROGNOTREGISTERED;
807  					goto error;
808  				}
809  				address = uaddr2taddr(nconf, ua);
810  				if (!address) {
811  					/* We don't know about your universal address */
812  					__warnx(TIRPC_DEBUG_FLAG_WARN, "%s: %s",
813  						__func__,
814  						clnt_sperrno(RPC_N2AXLATEFAILURE));
815  					client->cl_error.re_status =
816  								RPC_N2AXLATEFAILURE;
817  					goto done;
818  				}
819  				CLNT_CONTROL(client, CLGET_SVC_ADDR,
820  					     (char *)(void *)&servaddr);
821  				__rpc_fixup_addr(address, &servaddr);
822  				goto done;
823  			} else if (clnt_st == RPC_PROGVERSMISMATCH) {
824  				if (cc->cc_error.re_vers.low > RPCBVERS4) {
825  					client->cl_error = cc->cc_error;
826  					clnt_req_release(cc);
827  					goto error; /* a new version, can't handle */
828  				}
829  			} else if (clnt_st != RPC_PROGUNAVAIL) {
830  				/* Cant handle this error */
831  				client->cl_error = cc->cc_error;
832  				clnt_req_release(cc);
833  				goto error;
834  			}
835  			clnt_req_reset(cc);
836  		}
837  	
(2) Event null: At condition "address == NULL", the value of "address" must be "NULL".
(3) Event dead_error_condition: The condition "address == NULL" must be true.
(4) Event dead_error_line: Execution cannot reach the expression "address->len == 0U" inside this statement: "if (address == NULL || addr...".
Also see events: [assignment]
838  		if ((address == NULL) || (address->len == 0)) {
839  			client->cl_error.re_status = RPC_PROGNOTREGISTERED;
840  		}
841  		clnt_req_release(cc);
842  	
843  	 error:
844  		t = rpc_sperror(&client->cl_error, __func__);
845  	
846  		__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB, "%s", t);
847  		mem_free(t, RPC_SPERROR_BUFLEN);
848  	
849  	 done:
850  		if (ua)
851  			xdr_free((xdrproc_t) xdr_wrapstring, (char *)(void *)&ua);
852  		if (clpp)
853  			*clpp = client;
854  		else
855  			CLNT_DESTROY(client);
856  	
857  		if (parms.r_addr != NULL && parms.r_addr != nullstring)
858  			mem_free(parms.r_addr, 0);
859  		return (address);
860  	}
861  	
862  	/*
863  	 * Helper routine to find mapped address (for NLM).
864  	 */
865  	extern struct netbuf *
866  	rpcb_find_mapped_addr(char *nettype, rpcprog_t prog,
867  			      rpcvers_t vers, char *local_addr)
868  	{
869  		struct netbuf *nbuf;
870  		void *handle = __rpc_setconf(nettype);
871  		struct netconfig *nconf = __rpc_getconf(handle);
872  		nbuf = __rpcb_findaddr_timed(prog, vers, nconf, local_addr, NULL, NULL);
873  		__rpc_endconf(handle);
874  		return (nbuf);
875  	}
876  	
877  	/*
878  	 * Find the mapped address for program, version.
879  	 * Calls the rpcbind service remotely to do the lookup.
880  	 * Uses the transport specified in nconf.
881  	 * Returns false (0) if no map exists, else returns 1.
882  	 *
883  	 * Assuming that the address is all properly allocated
884  	 */
885  	bool
886  	rpcb_getaddr(rpcprog_t program, rpcvers_t version,
887  		     const struct netconfig *nconf, struct netbuf *address,
888  		     const char *host)
889  	{
890  		struct netbuf *na;
891  	
892  		na = __rpcb_findaddr_timed(
893  			program, version, (struct netconfig *)nconf,
894  			(char *)host, (CLIENT **) NULL,
895  			(struct timeval *)NULL);
896  		if (!na)
897  			return (false);
898  	
899  		if (na->len > address->maxlen) {
900  			/* Too long address */
901  			mem_free(na->buf, 0);
902  			mem_free(na, 0);
903  			__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB,
904  				"%s: address too long (%u > %u)",
905  				__func__, na->len, address->maxlen);
906  			return (false);
907  		}
908  		memcpy(address->buf, na->buf, (size_t) na->len);
909  		address->len = na->len;
910  		mem_free(na->buf, 0);
911  		mem_free(na, 0);
912  		return (true);
913  	}
914  	
915  	/*
916  	 * Get a copy of the current maps.
917  	 * Calls the rpcbind service remotely to get the maps.
918  	 *
919  	 * It returns only a list of the services
920  	 * It returns NULL on failure.
921  	 */
922  	rpcblist *
923  	rpcb_getmaps(const struct netconfig *nconf, const char *host)
924  	{
925  		rpcblist_ptr head = NULL;
926  		CLIENT *client;
927  		struct clnt_req *cc;
928  		char *t;
929  		enum clnt_stat clnt_st;
930  		rpcvers_t vers = 0;
931  	
932  		client = getclnthandle(host, nconf, NULL);
933  		if (CLNT_FAILURE(client)) {
934  			CLNT_DESTROY(client);
935  			return (head);
936  		}
937  	
938  		cc = mem_alloc(sizeof(*cc));
939  		clnt_req_fill(cc, client, authnone_ncreate(), RPCBPROC_DUMP,
940  			      (xdrproc_t) xdr_void, NULL,
941  			      (xdrproc_t) xdr_rpcblist_ptr, &head);
942  		clnt_st = clnt_req_setup(cc, to);
943  		if (clnt_st != RPC_SUCCESS)
944  			goto error;
945  	
946  		clnt_st = CLNT_CALL_WAIT(cc);
947  		if (clnt_st == RPC_SUCCESS)
948  			goto done;
949  	
950  		if ((clnt_st != RPC_PROGVERSMISMATCH) && (clnt_st != RPC_PROGUNAVAIL)) {
951  			goto error;
952  		}
953  	
954  		/* fall back to earlier version */
955  		CLNT_CONTROL(client, CLGET_VERS, (char *)(void *)&vers);
956  		if (vers == RPCBVERS4) {
957  			vers = RPCBVERS;
958  			CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&vers);
959  	
960  			clnt_req_reset(cc);
961  			clnt_st = clnt_req_setup(cc, to);
962  			if (clnt_st != RPC_SUCCESS)
963  				goto error;
964  	
965  			clnt_st = CLNT_CALL_WAIT(cc);
966  			if (clnt_st == RPC_SUCCESS)
967  				goto done;
968  		}
969  	
970  	 error:
971  		t = rpc_sperror(&cc->cc_error, __func__);
972  		__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s", t);
973  		mem_free(t, RPC_SPERROR_BUFLEN);
974  	
975  	 done:
976  		clnt_req_release(cc);
977  		CLNT_DESTROY(client);
978  		return (head);
979  	}
980  	
981  	/*
982  	 * rpcbinder remote-call-service interface.
983  	 * This routine is used to call the rpcbind remote call service
984  	 * which will look up a service program in the address maps, and then
985  	 * remotely call that routine with the given parameters. This allows
986  	 * programs to do a lookup and call in one step.
987  	 */
988  	enum clnt_stat
989  	rpcb_rmtcall(const struct netconfig *nconf, /* Netconfig structure */
990  		     const char *host, /* Remote host name */
991  		     const rpcprog_t prog, const rpcvers_t vers,
992  		     const rpcproc_t proc,/* Remote proc identifiers */
993  		     const xdrproc_t xdrargs, void *argsp,
994  		     const xdrproc_t xdrres, void *resp, /* Argument and Result */
995  		     const struct timeval tout,	/* Timeout value for this call */
996  		     const struct netbuf *addr_ptr
997  		     /* Preallocated netbuf address */)
998  	{
999  		CLIENT *client;
1000 		struct clnt_req *cc;
1001 		struct r_rpcb_rmtcallargs a;
1002 		struct r_rpcb_rmtcallres r;
1003 		struct timespec tv;
1004 		rpcvers_t rpcb_vers;
1005 		enum clnt_stat stat;
1006 	
1007 		client = getclnthandle(host, nconf, NULL);
1008 		if (CLNT_FAILURE(client)) {
1009 			CLNT_DESTROY(client);
1010 			return (RPC_FAILED);
1011 		}
1012 	
1013 		/*LINTED const castaway */
1014 		a.prog = prog;
1015 		a.vers = vers;
1016 		a.proc = proc;
1017 		a.args.args_val = argsp;
1018 		a.xdr_args = xdrargs;
1019 		r.addr = NULL;
1020 		r.results.results_val = resp;
1021 		r.xdr_res = xdrres;
1022 		tv.tv_sec = tout.tv_sec;
1023 		tv.tv_nsec = tout.tv_usec * 1000;
1024 	
1025 		cc = mem_alloc(sizeof(*cc));
1026 		clnt_req_fill(cc, client, authnone_ncreate(), RPCBPROC_CALLIT,
1027 			      (xdrproc_t) xdr_rpcb_rmtcallargs, &a,
1028 			      (xdrproc_t) xdr_rpcb_rmtcallres, &r);
1029 	
1030 		for (rpcb_vers = RPCBVERS4; rpcb_vers >= RPCBVERS; rpcb_vers--) {
1031 			CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&rpcb_vers);
1032 	
1033 			stat = clnt_req_setup(cc, tv);
1034 			if (stat == RPC_SUCCESS) {
1035 				stat = CLNT_CALL_WAIT(cc);
1036 			}
1037 	
1038 			if ((stat == RPC_SUCCESS) && (addr_ptr != NULL)) {
1039 				struct netbuf *na;
1040 				/*LINTED const castaway */
1041 				na = uaddr2taddr((struct netconfig *)nconf, r.addr);
1042 				if (!na) {
1043 					__warnx(TIRPC_DEBUG_FLAG_WARN, "%s: %s",
1044 						__func__,
1045 						clnt_sperrno(RPC_N2AXLATEFAILURE));
1046 					stat = RPC_N2AXLATEFAILURE;
1047 					/*LINTED const castaway */
1048 					((struct netbuf *)addr_ptr)->len = 0;
1049 					goto error;
1050 				}
1051 				if (na->len > addr_ptr->maxlen) {
1052 					/* Too long address */
1053 					__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB,
1054 						"%s: address too long (%u > %u)",
1055 						__func__, na->len, addr_ptr->maxlen);
1056 					stat = RPC_FAILED; /* XXX A better error no */
1057 					mem_free(na->buf, 0);	/* XXX */
1058 					mem_free(na, 0);
1059 					/*LINTED const castaway */
1060 					((struct netbuf *)addr_ptr)->len = 0;
1061 					goto error;
1062 				}
1063 				memcpy(addr_ptr->buf, na->buf, (size_t) na->len);
1064 				/*LINTED const castaway */
1065 				((struct netbuf *)addr_ptr)->len = na->len;
1066 				mem_free(na->buf, 0);
1067 				mem_free(na, 0);
1068 				break;
1069 			} else if ((stat != RPC_PROGVERSMISMATCH)
1070 				   && (stat != RPC_PROGUNAVAIL)) {
1071 				goto error;
1072 			}
1073 			clnt_req_reset(cc);
1074 		}
1075 	 error:
1076 		clnt_req_release(cc);
1077 		CLNT_DESTROY(client);
1078 		if (r.addr)
1079 			xdr_free((xdrproc_t) xdr_wrapstring, (char *)(void *)&r.addr);
1080 		return (stat);
1081 	}
1082 	
1083 	/*
1084 	 * Gets the time on the remote host.
1085 	 * Returns 1 if succeeds else 0.
1086 	 */
1087 	int
1088 	boolrpcb_gettime(const char *host, time_t *timep)
1089 	{
1090 		CLIENT *client = NULL;
1091 		struct clnt_req *cc;
1092 		void *handle;
1093 		struct netconfig *nconf;
1094 		rpcvers_t vers;
1095 		int32_t time32 = 0; 	/* old protocol 32-bits not long time_t */
1096 		enum clnt_stat st;
1097 	
1098 		if ((host == NULL) || (host[0] == 0)) {
1099 			time(timep);
1100 			return (true);
1101 		}
1102 	
1103 		handle = __rpc_setconf("netpath");
1104 		if (!handle) {
1105 			__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB, "%s: %s",
1106 				__func__, clnt_sperrno(RPC_UNKNOWNPROTO));
1107 			return (false);
1108 		}
1109 	
1110 		do {
1111 			if (client)
1112 				CLNT_DESTROY(client);
1113 	
1114 			nconf = __rpc_getconf(handle);
1115 			if (!nconf) {
1116 				__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB, "%s: %s",
1117 					__func__, clnt_sperrno(RPC_UNKNOWNPROTO));
1118 				break;
1119 			}
1120 			client = getclnthandle(host, nconf, NULL);
1121 		} while (CLNT_FAILURE(client));
1122 	
1123 		__rpc_endconf(handle);
1124 	
1125 		if (!client) {
1126 			return false;
1127 		}
1128 	
1129 		if (CLNT_FAILURE(client)) {
1130 			CLNT_DESTROY(client);
1131 			return (false);
1132 		}
1133 	
1134 		cc = mem_alloc(sizeof(*cc));
1135 		clnt_req_fill(cc, client, authnone_ncreate(), RPCBPROC_GETTIME,
1136 			      (xdrproc_t) xdr_void, NULL,
1137 			      (xdrproc_t) xdr_int32_t, &time32);
1138 		st = clnt_req_setup(cc, to);
1139 		if (st == RPC_SUCCESS) {
1140 			st = CLNT_CALL_WAIT(cc);
1141 		}
1142 	
1143 		if ((st == RPC_PROGVERSMISMATCH) || (st == RPC_PROGUNAVAIL)) {
1144 			CLNT_CONTROL(client, CLGET_VERS, (char *)(void *)&vers);
1145 			if (vers == RPCBVERS4) {
1146 				/* fall back to earlier version */
1147 				vers = RPCBVERS;
1148 				CLNT_CONTROL(client, CLSET_VERS, (char *)(void *)&vers);
1149 	
1150 				clnt_req_reset(cc);
1151 				st = clnt_req_setup(cc, to);
1152 				if (st == RPC_SUCCESS) {
1153 					st = CLNT_CALL_WAIT(cc);
1154 				}
1155 			}
1156 		}
1157 	
1158 		if (st != RPC_SUCCESS) {
1159 			char *t = rpc_sperror(&cc->cc_error, __func__);
1160 	
1161 			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s", t);
1162 			mem_free(t, RPC_SPERROR_BUFLEN);
1163 		}
1164 	
1165 		clnt_req_release(cc);
1166 		CLNT_DESTROY(client);
1167 		*timep = time32;
1168 		return (st == RPC_SUCCESS ? true : false);
1169 	}
1170 	
1171 	/*
1172 	 * Converts taddr to universal address.  This routine should never
1173 	 * really be called because local n2a libraries are always provided.
1174 	 */
1175 	char *rpcb_taddr2uaddr(struct netconfig *nconf, struct netbuf *taddr)
1176 	{
1177 		char *uaddr = NULL;
1178 		CLIENT *client;
1179 		struct clnt_req *cc;
1180 		enum clnt_stat st;
1181 	
1182 		/* parameter checking */
1183 		if (nconf == NULL) {
1184 			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %s",
1185 				__func__, clnt_sperrno(RPC_UNKNOWNPROTO));
1186 			return (NULL);
1187 		}
1188 		if (taddr == NULL) {
1189 			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %s",
1190 				__func__, clnt_sperrno(RPC_UNKNOWNADDR));
1191 			return (NULL);
1192 		}
1193 		client = local_rpcb(__func__);
1194 		if (CLNT_FAILURE(client)) {
1195 			CLNT_DESTROY(client);
1196 			return (false);
1197 		}
1198 	
1199 		cc = mem_alloc(sizeof(*cc));
1200 		clnt_req_fill(cc, client, authnone_ncreate(), RPCBPROC_TADDR2UADDR,
1201 			      (xdrproc_t) xdr_netbuf, taddr,
1202 			      (xdrproc_t) xdr_wrapstring, &uaddr);
1203 		st = clnt_req_setup(cc, to);
1204 		if (st == RPC_SUCCESS) {
1205 			st = CLNT_CALL_WAIT(cc);
1206 		}
1207 	
1208 		if (st != RPC_SUCCESS) {
1209 			char *t = rpc_sperror(&cc->cc_error, __func__);
1210 	
1211 			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s", t);
1212 			mem_free(t, RPC_SPERROR_BUFLEN);
1213 		}
1214 	
1215 		clnt_req_release(cc);
1216 		CLNT_DESTROY(client);
1217 		return (uaddr);
1218 	}
1219 	
1220 	/*
1221 	 * Converts universal address to netbuf.  This routine should never
1222 	 * really be called because local n2a libraries are always provided.
1223 	 */
1224 	struct netbuf *rpcb_uaddr2taddr(struct netconfig *nconf, char *uaddr)
1225 	{
1226 		struct netbuf *taddr;
1227 		CLIENT *client;
1228 		struct clnt_req *cc;
1229 		enum clnt_stat st;
1230 	
1231 		/* parameter checking */
1232 		if (nconf == NULL) {
1233 			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %s",
1234 				__func__, clnt_sperrno(RPC_UNKNOWNPROTO));
1235 			return (NULL);
1236 		}
1237 		if (uaddr == NULL) {
1238 			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %s",
1239 				__func__, clnt_sperrno(RPC_UNKNOWNADDR));
1240 			return (NULL);
1241 		}
1242 		client = local_rpcb(__func__);
1243 		if (CLNT_FAILURE(client)) {
1244 			CLNT_DESTROY(client);
1245 			return (false);
1246 		}
1247 	
1248 		cc = mem_alloc(sizeof(*cc));
1249 		taddr = (struct netbuf *)mem_zalloc(sizeof(struct netbuf));
1250 		clnt_req_fill(cc, client, authnone_ncreate(), RPCBPROC_UADDR2TADDR,
1251 			      (xdrproc_t) xdr_wrapstring, &uaddr,
1252 			      (xdrproc_t) xdr_netbuf, taddr);
1253 		st = clnt_req_setup(cc, to);
1254 		if (st == RPC_SUCCESS) {
1255 			st = CLNT_CALL_WAIT(cc);
1256 		}
1257 	
1258 		if (st != RPC_SUCCESS) {
1259 			char *t = rpc_sperror(&cc->cc_error, __func__);
1260 	
1261 			__warnx(TIRPC_DEBUG_FLAG_ERROR, "%s", t);
1262 			mem_free(t, RPC_SPERROR_BUFLEN);
1263 			mem_free(taddr, sizeof(*taddr));
1264 			taddr = NULL;
1265 		}
1266 	
1267 		clnt_req_release(cc);
1268 		CLNT_DESTROY(client);
1269 		return (taddr);
1270 	}
1271 	
1272 	/* XXX */
1273 	#define IN4_LOCALHOST_STRING "127.0.0.1"
1274 	#define IN6_LOCALHOST_STRING "::1"
1275 	
1276 	/*
1277 	 * This routine will return a client handle that is connected to the local
1278 	 * rpcbind.
1279 	 * On error, a CLIENT with cl_error.re_status set
1280 	 */
1281 	static CLIENT *local_rpcb(const char *tag)
1282 	{
1283 		CLIENT *client = NULL;
1284 		char *t;
1285 		static struct netconfig *loopnconf = NULL;
1286 		static char *hostname;
1287 		extern mutex_t loopnconf_lock;
1288 		struct netbuf nbuf;
1289 		struct sockaddr_un sun;
1290 		size_t tsize;
1291 		int sock;
1292 	
1293 		/*
1294 		 * Try connecting to the local rpcbind through a local socket
1295 		 * first. If this doesn't work, try all transports defined in
1296 		 * the netconfig file.
1297 		 */
1298 		memset(&sun, 0, sizeof(sun));
1299 		sock = socket(AF_LOCAL, SOCK_STREAM, 0);
1300 		if (sock < 0) {
1301 			/* For error codes */
1302 			client = clnt_raw_ncreate(RPCBPROG, RPCBVERS);
1303 			goto try_nconf;
1304 		}
1305 		sun.sun_family = AF_LOCAL;
1306 		strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
1307 		nbuf.len = SUN_LEN(&sun);
1308 		nbuf.maxlen = sizeof(struct sockaddr_un);
1309 		nbuf.buf = &sun;
1310 	
1311 		tsize = __rpc_get_t_size(AF_LOCAL, 0, 0);
1312 		client = clnt_vc_ncreatef(sock, &nbuf, (rpcprog_t) RPCBPROG,
1313 					  (rpcvers_t) RPCBVERS, tsize, tsize,
1314 					  CLNT_CREATE_FLAG_CLOSE |
1315 					  CLNT_CREATE_FLAG_CONNECT);
1316 	
1317 		if (CLNT_SUCCESS(client)) {
1318 			/* This is a local client (we created the fd above) */
1319 			client->cl_flags |= CLNT_FLAG_LOCAL;
1320 			return client;
1321 		}
1322 		t = rpc_sperror(&client->cl_error, tag);
1323 	
1324 		__warnx(TIRPC_DEBUG_FLAG_CLNT_RPCB, "%s", t);
1325 		mem_free(t, RPC_SPERROR_BUFLEN);
1326 	
1327 		/* Save client for error return */
1328 	
1329 		/* Nobody needs this socket anymore; free the descriptor. */
1330 		close(sock);
1331 	
1332 	 try_nconf:
1333 		/* VARIABLES PROTECTED BY loopnconf_lock: loopnconf */
1334 		mutex_lock(&loopnconf_lock);
1335 		if (loopnconf == NULL) {
1336 			struct netconfig *nconf, *tmpnconf = NULL;
1337 			void *nc_handle;
1338 			int fd;
1339 	
1340 			nc_handle = setnetconfig();
1341 			if (nc_handle == NULL) {
1342 				/* fails to open netconfig file */
1343 				syslog(LOG_ERR, "rpc: failed to open " NETCONFIG);
1344 				mutex_unlock(&loopnconf_lock);
1345 				__warnx(TIRPC_DEBUG_FLAG_WARN,
1346 					"%s(%s): failed to open " NETCONFIG " %s",
1347 					__func__, tag, clnt_sperrno(RPC_UNKNOWNPROTO));
1348 				client->cl_error.re_status = RPC_UNKNOWNPROTO;
1349 				return (client);
1350 			}
1351 			while ((nconf = getnetconfig(nc_handle)) != NULL) {
1352 	#ifdef INET6
1353 				if ((strcmp(nconf->nc_protofmly, NC_INET6) == 0 ||
1354 	#else
1355 				if ((
1356 	#endif
1357 					    strcmp(nconf->nc_protofmly, NC_INET) == 0)
1358 				    && (nconf->nc_semantics == NC_TPI_COTS
1359 					|| nconf->nc_semantics == NC_TPI_COTS_ORD)) {
1360 					fd = __rpc_nconf2fd(nconf);
1361 					/*
1362 					 * Can't create a socket, assume that
1363 					 * this family isn't configured in the kernel.
1364 					 */
1365 					if (fd < 0)
1366 						continue;
1367 					close(fd);
1368 					tmpnconf = nconf;
1369 					if (!strcmp(nconf->nc_protofmly, NC_INET))
1370 						hostname = IN4_LOCALHOST_STRING;
1371 					else
1372 						hostname = IN6_LOCALHOST_STRING;
1373 				}
1374 			}
1375 			if (tmpnconf == NULL) {
1376 				endnetconfig(nc_handle);
1377 				mutex_unlock(&loopnconf_lock);
1378 				__warnx(TIRPC_DEBUG_FLAG_WARN,
1379 					"%s(%s): failed to find " NETCONFIG " %s",
1380 					__func__, tag, clnt_sperrno(RPC_UNKNOWNPROTO));
1381 				client->cl_error.re_status = RPC_UNKNOWNPROTO;
1382 				return (client);
1383 			}
1384 			loopnconf = getnetconfigent(tmpnconf->nc_netid);
1385 			/* loopnconf is never freed */
1386 			endnetconfig(nc_handle);
1387 		}
1388 		mutex_unlock(&loopnconf_lock);
1389 		/* Free client used for errors before */
1390 		CLNT_DESTROY(client);
1391 	
1392 		client = getclnthandle(hostname, loopnconf, NULL);
1393 		return (client);
1394 	}
1395