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
pmap_set(rpcprog_t program,rpcvers_t version,rpcprot_t protocol,u_int port)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
pmap_unset(rpcprog_t program,rpcvers_t version)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