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 void clnt_perror(); 58 59 /* 60 * Set a mapping between program,version and port. 61 * Calls the pmap service remotely to do the mapping. 62 */ 63 bool_t 64 pmap_set( 65 rpcprog_t program, 66 rpcvers_t version, 67 rpcprot_t protocol, 68 u_int port) 69 { 70 struct sockaddr_in myaddress; 71 int sock = -1; 72 CLIENT *client; 73 struct pmap parms; 74 bool_t rslt; 75 76 get_myaddress(&myaddress); 77 client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, 78 timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); 79 if (client == (CLIENT *)NULL) 80 return (FALSE); 81 parms.pm_prog = program; 82 parms.pm_vers = version; 83 parms.pm_prot = protocol; 84 parms.pm_port = port; 85 #if TARGET_OS_MAC 86 { 87 /* 88 * Poke launchd, then wait for portmap to start up. 89 * 90 * My impression is that the protocol involves getting 91 * something back from the server. So wait, briefly, to 92 * see if it's going to send us something. Then continue 93 * on, regardless. I don't actually check what the data 94 * is, because I have no idea what sort of validation, if 95 * any, is needed. 96 * 97 * However, for whatever reason, the socket seems to be 98 * mode 700 owner root on my system, so if you don't 99 * change its ownership or mode, and if the program isn't 100 * running as root, you still lose. 101 */ 102 #define TICKLER_SOCKET "/var/run/portmap.socket" 103 int tickle; 104 struct sockaddr_un a = { 105 .sun_family = AF_UNIX, 106 .sun_path = TICKLER_SOCKET, 107 .sun_len = (sizeof(TICKLER_SOCKET) 108 + offsetof(struct sockaddr_un, sun_path)), 109 }; 110 111 if (sizeof(TICKLER_SOCKET) <= sizeof(a.sun_path)) { 112 tickle = socket(AF_UNIX, SOCK_STREAM, 0); 113 if (tickle >= 0) { 114 if (connect(tickle, (struct sockaddr *)&a, a.sun_len) == 0 115 && tickle < FD_SETSIZE) { 116 fd_set readfds; 117 struct timeval tv; 118 119 FD_ZERO(&readfds); 120 /* XXX Range check. */ 121 FD_SET(tickle, &readfds); 122 tv.tv_sec = 5; 123 tv.tv_usec = 0; 124 (void) select(tickle+1, &readfds, 0, 0, &tv); 125 } 126 close(tickle); 127 } 128 } 129 } 130 #endif 131 if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt, 132 tottimeout) != RPC_SUCCESS) { 133 clnt_perror(client, "Cannot register service"); 134 return (FALSE); 135 } 136 CLNT_DESTROY(client); 137 (void)close(sock); 138 return (rslt); 139 } 140 141 /* 142 * Remove the mapping between program,version and port. 143 * Calls the pmap service remotely to do the un-mapping. 144 */ 145 bool_t 146 pmap_unset( 147 rpcprog_t program, 148 rpcvers_t version) 149 { 150 struct sockaddr_in myaddress; 151 int sock = -1; 152 CLIENT *client; 153 struct pmap parms; 154 bool_t rslt; 155 156 get_myaddress(&myaddress); 157 client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, 158 timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); 159 if (client == (CLIENT *)NULL) 160 return (FALSE); 161 parms.pm_prog = program; 162 parms.pm_vers = version; 163 parms.pm_port = parms.pm_prot = 0; 164 CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt, 165 tottimeout); 166 CLNT_DESTROY(client); 167 (void)close(sock); 168 return (rslt); 169 } 170