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