1 /* @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC */ 2 /* 3 * Copyright (c) 2010, Oracle America, Inc. 4 * 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * * Neither the name of the "Oracle America, Inc." nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 23 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 28 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 #if !defined(lint) && defined(SCCSIDS) 35 static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro"; 36 #endif 37 38 /* 39 * pmap_clnt.c 40 * Client interface to pmap rpc service. 41 */ 42 43 #include <unistd.h> 44 #include <gssrpc/rpc.h> 45 #include <gssrpc/pmap_prot.h> 46 #include <gssrpc/pmap_clnt.h> 47 48 #if TARGET_OS_MAC 49 #include <sys/un.h> 50 #include <string.h> 51 #include <syslog.h> 52 #endif 53 54 static struct timeval timeout = { 5, 0 }; 55 static struct timeval tottimeout = { 60, 0 }; 56 57 /* 58 * Set a mapping between program,version and port. 59 * Calls the pmap service remotely to do the mapping. 60 */ 61 bool_t 62 pmap_set( 63 rpcprog_t program, 64 rpcvers_t version, 65 rpcprot_t protocol, 66 u_int port) 67 { 68 struct sockaddr_in myaddress; 69 int sock = -1; 70 CLIENT *client; 71 struct pmap parms; 72 bool_t rslt; 73 74 get_myaddress(&myaddress); 75 client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, 76 timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); 77 if (client == (CLIENT *)NULL) 78 return (FALSE); 79 parms.pm_prog = program; 80 parms.pm_vers = version; 81 parms.pm_prot = protocol; 82 parms.pm_port = port; 83 #if TARGET_OS_MAC 84 { 85 /* 86 * Poke launchd, then wait for portmap to start up. 87 * 88 * My impression is that the protocol involves getting 89 * something back from the server. So wait, briefly, to 90 * see if it's going to send us something. Then continue 91 * on, regardless. I don't actually check what the data 92 * is, because I have no idea what sort of validation, if 93 * any, is needed. 94 * 95 * However, for whatever reason, the socket seems to be 96 * mode 700 owner root on my system, so if you don't 97 * change its ownership or mode, and if the program isn't 98 * running as root, you still lose. 99 */ 100 #define TICKLER_SOCKET "/var/run/portmap.socket" 101 int tickle; 102 struct sockaddr_un a = { 103 .sun_family = AF_UNIX, 104 .sun_path = TICKLER_SOCKET, 105 .sun_len = (sizeof(TICKLER_SOCKET) 106 + offsetof(struct sockaddr_un, sun_path)), 107 }; 108 109 if (sizeof(TICKLER_SOCKET) <= sizeof(a.sun_path)) { 110 tickle = socket(AF_UNIX, SOCK_STREAM, 0); 111 if (tickle >= 0) { 112 if (connect(tickle, (struct sockaddr *)&a, a.sun_len) == 0 113 && tickle < FD_SETSIZE) { 114 fd_set readfds; 115 struct timeval tv; 116 117 FD_ZERO(&readfds); 118 /* XXX Range check. */ 119 FD_SET(tickle, &readfds); 120 tv.tv_sec = 5; 121 tv.tv_usec = 0; 122 (void) select(tickle+1, &readfds, 0, 0, &tv); 123 } 124 close(tickle); 125 } 126 } 127 } 128 #endif 129 if (CLNT_CALL(client, PMAPPROC_SET, (xdrproc_t)xdr_pmap, &parms, 130 (xdrproc_t)xdr_bool, &rslt, 131 tottimeout) != RPC_SUCCESS) { 132 clnt_perror(client, "Cannot register service"); 133 return (FALSE); 134 } 135 CLNT_DESTROY(client); 136 (void)close(sock); 137 return (rslt); 138 } 139 140 /* 141 * Remove the mapping between program,version and port. 142 * Calls the pmap service remotely to do the un-mapping. 143 */ 144 bool_t 145 pmap_unset( 146 rpcprog_t program, 147 rpcvers_t version) 148 { 149 struct sockaddr_in myaddress; 150 int sock = -1; 151 CLIENT *client; 152 struct pmap parms; 153 bool_t rslt; 154 155 get_myaddress(&myaddress); 156 client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, 157 timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); 158 if (client == (CLIENT *)NULL) 159 return (FALSE); 160 parms.pm_prog = program; 161 parms.pm_vers = version; 162 parms.pm_port = parms.pm_prot = 0; 163 CLNT_CALL(client, PMAPPROC_UNSET, (xdrproc_t)xdr_pmap, &parms, 164 (xdrproc_t)xdr_bool, &rslt, tottimeout); 165 CLNT_DESTROY(client); 166 (void)close(sock); 167 return (rslt); 168 } 169