xref: /titanic_51/usr/src/lib/libnsl/rpc/pmap_clnt.c (revision 9ff75ade7518b5023d90c864a4c081dba319589e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
59acbbeafSnn35248  * Common Development and Distribution License (the "License").
69acbbeafSnn35248  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
2061961e0fSrobinson  */
2161961e0fSrobinson 
2261961e0fSrobinson /*
23*9ff75adeSSurya Prakki  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
25e8031f0aSraf 
267c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /* All Rights Reserved */
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
307c478bd9Sstevel@tonic-gate  * 4.3 BSD under license from the Regents of the University of
317c478bd9Sstevel@tonic-gate  * California.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #ifdef PORTMAP
359acbbeafSnn35248 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate  * interface to pmap rpc service.
387c478bd9Sstevel@tonic-gate  */
39e8031f0aSraf #include "mt.h"
407c478bd9Sstevel@tonic-gate #include "rpc_mt.h"
417c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
427c478bd9Sstevel@tonic-gate #include <rpc/nettype.h>
437c478bd9Sstevel@tonic-gate #include <netdir.h>
447c478bd9Sstevel@tonic-gate #include <rpc/pmap_prot.h>
457c478bd9Sstevel@tonic-gate #include <rpc/pmap_clnt.h>
467c478bd9Sstevel@tonic-gate #include <rpc/pmap_rmt.h>
479acbbeafSnn35248 #include <string.h>
487c478bd9Sstevel@tonic-gate #include <syslog.h>
497c478bd9Sstevel@tonic-gate #include <netinet/in.h>
507c478bd9Sstevel@tonic-gate #include <sys/socket.h>
519acbbeafSnn35248 #include <unistd.h>
527c478bd9Sstevel@tonic-gate 
539acbbeafSnn35248 int use_portmapper = 0;
547c478bd9Sstevel@tonic-gate static const struct timeval timeout = { 5, 0 };
557c478bd9Sstevel@tonic-gate static const struct timeval tottimeout = { 60, 0 };
567c478bd9Sstevel@tonic-gate static const struct timeval rmttimeout = { 3, 0 };
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate  * Set a mapping between program, version and port.
607c478bd9Sstevel@tonic-gate  * Calls the pmap service remotely to do the mapping.
617c478bd9Sstevel@tonic-gate  */
627c478bd9Sstevel@tonic-gate bool_t
6361961e0fSrobinson pmap_set(rpcprog_t program, rpcvers_t version, rpcprot_t protocol,
6461961e0fSrobinson 								ushort_t port)
657c478bd9Sstevel@tonic-gate {
667c478bd9Sstevel@tonic-gate 	bool_t rslt;
677c478bd9Sstevel@tonic-gate 	struct netbuf *na;
687c478bd9Sstevel@tonic-gate 	struct netconfig *nconf;
697c478bd9Sstevel@tonic-gate 	char buf[32];
707c478bd9Sstevel@tonic-gate 
7161961e0fSrobinson 	if ((protocol != IPPROTO_UDP) && (protocol != IPPROTO_TCP))
727c478bd9Sstevel@tonic-gate 		return (FALSE);
737c478bd9Sstevel@tonic-gate 	nconf = __rpc_getconfip(protocol == IPPROTO_UDP ? "udp" : "tcp");
7461961e0fSrobinson 	if (!nconf)
757c478bd9Sstevel@tonic-gate 		return (FALSE);
7661961e0fSrobinson 	(void) sprintf(buf, "0.0.0.0.%d.%d", port >> 8 & 0xff, port & 0xff);
777c478bd9Sstevel@tonic-gate 	na = uaddr2taddr(nconf, buf);
787c478bd9Sstevel@tonic-gate 	if (!na) {
797c478bd9Sstevel@tonic-gate 		freenetconfigent(nconf);
807c478bd9Sstevel@tonic-gate 		return (FALSE);
817c478bd9Sstevel@tonic-gate 	}
827c478bd9Sstevel@tonic-gate 	rslt = rpcb_set(program, version, nconf, na);
83*9ff75adeSSurya Prakki 
847c478bd9Sstevel@tonic-gate 	netdir_free((char *)na, ND_ADDR);
857c478bd9Sstevel@tonic-gate 	freenetconfigent(nconf);
867c478bd9Sstevel@tonic-gate 	return (rslt);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate /*
907c478bd9Sstevel@tonic-gate  * Remove the mapping between program, version and port.
917c478bd9Sstevel@tonic-gate  * Calls the pmap service remotely to do the un-mapping.
927c478bd9Sstevel@tonic-gate  */
937c478bd9Sstevel@tonic-gate bool_t
9461961e0fSrobinson pmap_unset(rpcprog_t program, rpcvers_t version)
957c478bd9Sstevel@tonic-gate {
967c478bd9Sstevel@tonic-gate 	struct netconfig *nconf;
977c478bd9Sstevel@tonic-gate 	bool_t udp_rslt = FALSE;
987c478bd9Sstevel@tonic-gate 	bool_t tcp_rslt = FALSE;
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	nconf = __rpc_getconfip("udp");
1017c478bd9Sstevel@tonic-gate 	if (nconf) {
1027c478bd9Sstevel@tonic-gate 		udp_rslt = rpcb_unset(program, version, nconf);
1037c478bd9Sstevel@tonic-gate 		freenetconfigent(nconf);
1047c478bd9Sstevel@tonic-gate 	}
1057c478bd9Sstevel@tonic-gate 	nconf = __rpc_getconfip("tcp");
1067c478bd9Sstevel@tonic-gate 	if (nconf) {
1077c478bd9Sstevel@tonic-gate 		tcp_rslt = rpcb_unset(program, version, nconf);
1087c478bd9Sstevel@tonic-gate 		freenetconfigent(nconf);
1097c478bd9Sstevel@tonic-gate 	}
1107c478bd9Sstevel@tonic-gate 	/*
1117c478bd9Sstevel@tonic-gate 	 * XXX: The call may still succeed even if only one of the
1127c478bd9Sstevel@tonic-gate 	 * calls succeeded.  This was the best that could be
1137c478bd9Sstevel@tonic-gate 	 * done for backward compatibility.
1147c478bd9Sstevel@tonic-gate 	 */
1157c478bd9Sstevel@tonic-gate 	return (tcp_rslt || udp_rslt);
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate /*
1197c478bd9Sstevel@tonic-gate  * Find the mapped port for program, version.
1207c478bd9Sstevel@tonic-gate  * Calls the pmap service remotely to do the lookup.
1217c478bd9Sstevel@tonic-gate  * Returns 0 if no map exists.
1227c478bd9Sstevel@tonic-gate  *
1237c478bd9Sstevel@tonic-gate  * XXX: It talks only to the portmapper and not to the rpcbind
1247c478bd9Sstevel@tonic-gate  * service.  There may be implementations out there which do not
1257c478bd9Sstevel@tonic-gate  * run portmapper as a part of rpcbind.
1267c478bd9Sstevel@tonic-gate  */
12761961e0fSrobinson ushort_t
12861961e0fSrobinson pmap_getport(struct sockaddr_in *address, rpcprog_t program,
12961961e0fSrobinson 					rpcvers_t version, rpcprot_t protocol)
1307c478bd9Sstevel@tonic-gate {
13161961e0fSrobinson 	ushort_t port = 0;
1327c478bd9Sstevel@tonic-gate 	int fd = RPC_ANYFD;
13361961e0fSrobinson 	CLIENT *client;
1347c478bd9Sstevel@tonic-gate 	struct pmap parms;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	address->sin_port = htons(PMAPPORT);
1377c478bd9Sstevel@tonic-gate 	client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout,
1387c478bd9Sstevel@tonic-gate 				&fd, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
13961961e0fSrobinson 	if (client != NULL) {
1407c478bd9Sstevel@tonic-gate 		parms.pm_prog = program;
1417c478bd9Sstevel@tonic-gate 		parms.pm_vers = version;
1427c478bd9Sstevel@tonic-gate 		parms.pm_prot = protocol;
1437c478bd9Sstevel@tonic-gate 		parms.pm_port = 0;	/* not needed or used */
1447c478bd9Sstevel@tonic-gate 		if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap,
1457c478bd9Sstevel@tonic-gate 			    (caddr_t)&parms, (xdrproc_t)xdr_u_short,
1467c478bd9Sstevel@tonic-gate 			    (caddr_t)&port, tottimeout) != RPC_SUCCESS) {
1477c478bd9Sstevel@tonic-gate 			rpc_createerr.cf_stat = RPC_PMAPFAILURE;
1487c478bd9Sstevel@tonic-gate 			clnt_geterr(client, &rpc_createerr.cf_error);
1497c478bd9Sstevel@tonic-gate 		} else if (port == 0) {
1507c478bd9Sstevel@tonic-gate 			rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
1517c478bd9Sstevel@tonic-gate 		}
1527c478bd9Sstevel@tonic-gate 		CLNT_DESTROY(client);
1537c478bd9Sstevel@tonic-gate 	}
1547c478bd9Sstevel@tonic-gate 	address->sin_port = 0;
1557c478bd9Sstevel@tonic-gate 	return (port);
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate /*
1597c478bd9Sstevel@tonic-gate  * Get a copy of the current port maps.
1607c478bd9Sstevel@tonic-gate  * Calls the pmap service remotely to do get the maps.
1617c478bd9Sstevel@tonic-gate  */
1627c478bd9Sstevel@tonic-gate struct pmaplist *
16361961e0fSrobinson pmap_getmaps(struct sockaddr_in *address)
1647c478bd9Sstevel@tonic-gate {
16561961e0fSrobinson 	pmaplist_ptr head = NULL;
1667c478bd9Sstevel@tonic-gate 	int fd = RPC_ANYFD;
1677c478bd9Sstevel@tonic-gate 	struct timeval minutetimeout;
16861961e0fSrobinson 	CLIENT *client;
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 	minutetimeout.tv_sec = 60;
1717c478bd9Sstevel@tonic-gate 	minutetimeout.tv_usec = 0;
1727c478bd9Sstevel@tonic-gate 	address->sin_port = htons(PMAPPORT);
1737c478bd9Sstevel@tonic-gate 	client = clnttcp_create(address, PMAPPROG, PMAPVERS, &fd, 50, 500);
17461961e0fSrobinson 	if (client != NULL) {
1757c478bd9Sstevel@tonic-gate 		if (CLNT_CALL(client, PMAPPROC_DUMP, (xdrproc_t)xdr_void,
17661961e0fSrobinson 			    NULL, (xdrproc_t)xdr_pmaplist_ptr,
1777c478bd9Sstevel@tonic-gate 			    (caddr_t)&head, minutetimeout) != RPC_SUCCESS) {
17861961e0fSrobinson 			(void) syslog(LOG_ERR, "%s",
1797c478bd9Sstevel@tonic-gate 			clnt_sperror(client, "pmap_getmaps rpc problem"));
1807c478bd9Sstevel@tonic-gate 		}
1817c478bd9Sstevel@tonic-gate 		CLNT_DESTROY(client);
1827c478bd9Sstevel@tonic-gate 	}
1837c478bd9Sstevel@tonic-gate 	address->sin_port = 0;
1847c478bd9Sstevel@tonic-gate 	return ((struct pmaplist *)head);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate /*
1887c478bd9Sstevel@tonic-gate  * pmapper remote-call-service interface.
1897c478bd9Sstevel@tonic-gate  * This routine is used to call the pmapper remote call service
1907c478bd9Sstevel@tonic-gate  * which will look up a service program in the port maps, and then
1917c478bd9Sstevel@tonic-gate  * remotely call that routine with the given parameters. This allows
1927c478bd9Sstevel@tonic-gate  * programs to do a lookup and call in one step.
1937c478bd9Sstevel@tonic-gate  */
1947c478bd9Sstevel@tonic-gate enum clnt_stat
19561961e0fSrobinson pmap_rmtcall(struct sockaddr_in *addr, rpcprog_t prog, rpcvers_t vers,
19661961e0fSrobinson 	rpcproc_t proc, xdrproc_t xdrargs, caddr_t argsp, xdrproc_t xdrres,
19761961e0fSrobinson 	caddr_t resp, struct timeval tout, rpcport_t *port_ptr)
1987c478bd9Sstevel@tonic-gate {
1997c478bd9Sstevel@tonic-gate 	int fd = RPC_ANYFD;
20061961e0fSrobinson 	CLIENT *client;
2017c478bd9Sstevel@tonic-gate 	struct p_rmtcallargs a;
2027c478bd9Sstevel@tonic-gate 	struct p_rmtcallres r;
2037c478bd9Sstevel@tonic-gate 	enum clnt_stat stat;
2047c478bd9Sstevel@tonic-gate 	short tmp = addr->sin_port;
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	addr->sin_port = htons(PMAPPORT);
2077c478bd9Sstevel@tonic-gate 	client = clntudp_create(addr, PMAPPROG, PMAPVERS, rmttimeout, &fd);
20861961e0fSrobinson 	if (client != NULL) {
2097c478bd9Sstevel@tonic-gate 		a.prog = prog;
2107c478bd9Sstevel@tonic-gate 		a.vers = vers;
2117c478bd9Sstevel@tonic-gate 		a.proc = proc;
2127c478bd9Sstevel@tonic-gate 		a.args.args_val = argsp;
2137c478bd9Sstevel@tonic-gate 		a.xdr_args = xdrargs;
2147c478bd9Sstevel@tonic-gate 		r.res.res_val = resp;
2157c478bd9Sstevel@tonic-gate 		r.xdr_res = xdrres;
2167c478bd9Sstevel@tonic-gate 		stat = CLNT_CALL(client, PMAPPROC_CALLIT,
2177c478bd9Sstevel@tonic-gate 				(xdrproc_t)xdr_rmtcallargs,
2187c478bd9Sstevel@tonic-gate 				(caddr_t)&a, (xdrproc_t)xdr_rmtcallres,
2197c478bd9Sstevel@tonic-gate 				(caddr_t)&r, tout);
2207c478bd9Sstevel@tonic-gate 		CLNT_DESTROY(client);
2217c478bd9Sstevel@tonic-gate 	} else {
2227c478bd9Sstevel@tonic-gate 		stat = RPC_FAILED;
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate 	addr->sin_port = tmp;
2257c478bd9Sstevel@tonic-gate 	*port_ptr = r.port;
2267c478bd9Sstevel@tonic-gate 	return (stat);
2277c478bd9Sstevel@tonic-gate }
2289acbbeafSnn35248 
2297c478bd9Sstevel@tonic-gate #endif /* PORTMAP */
230