1*11be35a1SLionel Sambuc /* $NetBSD: check_bound.c,v 1.1 2010/07/26 15:53:00 pooka Exp $ */
2*11be35a1SLionel Sambuc
3*11be35a1SLionel Sambuc /*
4*11be35a1SLionel Sambuc * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5*11be35a1SLionel Sambuc * unrestricted use provided that this legend is included on all tape
6*11be35a1SLionel Sambuc * media and as a part of the software program in whole or part. Users
7*11be35a1SLionel Sambuc * may copy or modify Sun RPC without charge, but are not authorized
8*11be35a1SLionel Sambuc * to license or distribute it to anyone else except as part of a product or
9*11be35a1SLionel Sambuc * program developed by the user.
10*11be35a1SLionel Sambuc *
11*11be35a1SLionel Sambuc * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12*11be35a1SLionel Sambuc * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13*11be35a1SLionel Sambuc * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14*11be35a1SLionel Sambuc *
15*11be35a1SLionel Sambuc * Sun RPC is provided with no support and without any obligation on the
16*11be35a1SLionel Sambuc * part of Sun Microsystems, Inc. to assist in its use, correction,
17*11be35a1SLionel Sambuc * modification or enhancement.
18*11be35a1SLionel Sambuc *
19*11be35a1SLionel Sambuc * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20*11be35a1SLionel Sambuc * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21*11be35a1SLionel Sambuc * OR ANY PART THEREOF.
22*11be35a1SLionel Sambuc *
23*11be35a1SLionel Sambuc * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24*11be35a1SLionel Sambuc * or profits or other special, indirect and consequential damages, even if
25*11be35a1SLionel Sambuc * Sun has been advised of the possibility of such damages.
26*11be35a1SLionel Sambuc *
27*11be35a1SLionel Sambuc * Sun Microsystems, Inc.
28*11be35a1SLionel Sambuc * 2550 Garcia Avenue
29*11be35a1SLionel Sambuc * Mountain View, California 94043
30*11be35a1SLionel Sambuc */
31*11be35a1SLionel Sambuc /*
32*11be35a1SLionel Sambuc * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
33*11be35a1SLionel Sambuc */
34*11be35a1SLionel Sambuc
35*11be35a1SLionel Sambuc /* #ident "@(#)check_bound.c 1.15 93/07/05 SMI" */
36*11be35a1SLionel Sambuc
37*11be35a1SLionel Sambuc #if 0
38*11be35a1SLionel Sambuc #ifndef lint
39*11be35a1SLionel Sambuc static char sccsid[] = "@(#)check_bound.c 1.11 89/04/21 Copyr 1989 Sun Micro";
40*11be35a1SLionel Sambuc #endif
41*11be35a1SLionel Sambuc #endif
42*11be35a1SLionel Sambuc
43*11be35a1SLionel Sambuc /*
44*11be35a1SLionel Sambuc * check_bound.c
45*11be35a1SLionel Sambuc * Checks to see whether the program is still bound to the
46*11be35a1SLionel Sambuc * claimed address and returns the univeral merged address
47*11be35a1SLionel Sambuc *
48*11be35a1SLionel Sambuc */
49*11be35a1SLionel Sambuc
50*11be35a1SLionel Sambuc #include <sys/types.h>
51*11be35a1SLionel Sambuc #include <sys/socket.h>
52*11be35a1SLionel Sambuc #include <rpc/rpc.h>
53*11be35a1SLionel Sambuc #include <stdio.h>
54*11be35a1SLionel Sambuc #include <netconfig.h>
55*11be35a1SLionel Sambuc #include <syslog.h>
56*11be35a1SLionel Sambuc #include <string.h>
57*11be35a1SLionel Sambuc #include <unistd.h>
58*11be35a1SLionel Sambuc #include <stdlib.h>
59*11be35a1SLionel Sambuc
60*11be35a1SLionel Sambuc #include <rump/rump.h>
61*11be35a1SLionel Sambuc #include <rump/rump_syscalls.h>
62*11be35a1SLionel Sambuc
63*11be35a1SLionel Sambuc #include "rpcbind.h"
64*11be35a1SLionel Sambuc
65*11be35a1SLionel Sambuc struct fdlist {
66*11be35a1SLionel Sambuc int fd;
67*11be35a1SLionel Sambuc struct netconfig *nconf;
68*11be35a1SLionel Sambuc struct fdlist *next;
69*11be35a1SLionel Sambuc int check_binding;
70*11be35a1SLionel Sambuc };
71*11be35a1SLionel Sambuc
72*11be35a1SLionel Sambuc static struct fdlist *fdhead; /* Link list of the check fd's */
73*11be35a1SLionel Sambuc static struct fdlist *fdtail;
74*11be35a1SLionel Sambuc static const char emptystring[] = "";
75*11be35a1SLionel Sambuc
76*11be35a1SLionel Sambuc static bool_t check_bound(struct fdlist *, const char *uaddr);
77*11be35a1SLionel Sambuc
78*11be35a1SLionel Sambuc /*
79*11be35a1SLionel Sambuc * Returns 1 if the given address is bound for the given addr & transport
80*11be35a1SLionel Sambuc * For all error cases, we assume that the address is bound
81*11be35a1SLionel Sambuc * Returns 0 for success.
82*11be35a1SLionel Sambuc */
83*11be35a1SLionel Sambuc static bool_t
check_bound(struct fdlist * fdl,const char * uaddr)84*11be35a1SLionel Sambuc check_bound(struct fdlist *fdl, const char *uaddr)
85*11be35a1SLionel Sambuc {
86*11be35a1SLionel Sambuc int fd;
87*11be35a1SLionel Sambuc struct netbuf *na;
88*11be35a1SLionel Sambuc int ans;
89*11be35a1SLionel Sambuc
90*11be35a1SLionel Sambuc if (fdl->check_binding == FALSE)
91*11be35a1SLionel Sambuc return (TRUE);
92*11be35a1SLionel Sambuc
93*11be35a1SLionel Sambuc na = uaddr2taddr(fdl->nconf, uaddr);
94*11be35a1SLionel Sambuc if (!na)
95*11be35a1SLionel Sambuc return (TRUE); /* punt, should never happen */
96*11be35a1SLionel Sambuc
97*11be35a1SLionel Sambuc fd = __rpc_nconf2fd(fdl->nconf);
98*11be35a1SLionel Sambuc if (fd < 0) {
99*11be35a1SLionel Sambuc free(na);
100*11be35a1SLionel Sambuc return (TRUE);
101*11be35a1SLionel Sambuc }
102*11be35a1SLionel Sambuc
103*11be35a1SLionel Sambuc ans = bind(fd, (struct sockaddr *)na->buf, na->len);
104*11be35a1SLionel Sambuc
105*11be35a1SLionel Sambuc rump_sys_close(fd);
106*11be35a1SLionel Sambuc free(na);
107*11be35a1SLionel Sambuc
108*11be35a1SLionel Sambuc return (ans == 0 ? FALSE : TRUE);
109*11be35a1SLionel Sambuc }
110*11be35a1SLionel Sambuc
111*11be35a1SLionel Sambuc int
add_bndlist(struct netconfig * nconf,struct netbuf * baddr)112*11be35a1SLionel Sambuc add_bndlist(struct netconfig *nconf, struct netbuf *baddr)
113*11be35a1SLionel Sambuc {
114*11be35a1SLionel Sambuc struct fdlist *fdl;
115*11be35a1SLionel Sambuc struct netconfig *newnconf;
116*11be35a1SLionel Sambuc
117*11be35a1SLionel Sambuc newnconf = getnetconfigent(nconf->nc_netid);
118*11be35a1SLionel Sambuc if (newnconf == NULL)
119*11be35a1SLionel Sambuc return (-1);
120*11be35a1SLionel Sambuc fdl = (struct fdlist *)malloc((u_int)sizeof (struct fdlist));
121*11be35a1SLionel Sambuc if (fdl == NULL) {
122*11be35a1SLionel Sambuc freenetconfigent(newnconf);
123*11be35a1SLionel Sambuc syslog(LOG_ERR, "no memory!");
124*11be35a1SLionel Sambuc return (-1);
125*11be35a1SLionel Sambuc }
126*11be35a1SLionel Sambuc fdl->nconf = newnconf;
127*11be35a1SLionel Sambuc fdl->next = NULL;
128*11be35a1SLionel Sambuc if (fdhead == NULL) {
129*11be35a1SLionel Sambuc fdhead = fdl;
130*11be35a1SLionel Sambuc fdtail = fdl;
131*11be35a1SLionel Sambuc } else {
132*11be35a1SLionel Sambuc fdtail->next = fdl;
133*11be35a1SLionel Sambuc fdtail = fdl;
134*11be35a1SLionel Sambuc }
135*11be35a1SLionel Sambuc /* XXX no bound checking for now */
136*11be35a1SLionel Sambuc fdl->check_binding = FALSE;
137*11be35a1SLionel Sambuc
138*11be35a1SLionel Sambuc return 0;
139*11be35a1SLionel Sambuc }
140*11be35a1SLionel Sambuc
141*11be35a1SLionel Sambuc bool_t
is_bound(const char * netid,const char * uaddr)142*11be35a1SLionel Sambuc is_bound(const char *netid, const char *uaddr)
143*11be35a1SLionel Sambuc {
144*11be35a1SLionel Sambuc struct fdlist *fdl;
145*11be35a1SLionel Sambuc
146*11be35a1SLionel Sambuc for (fdl = fdhead; fdl; fdl = fdl->next)
147*11be35a1SLionel Sambuc if (strcmp(fdl->nconf->nc_netid, netid) == 0)
148*11be35a1SLionel Sambuc break;
149*11be35a1SLionel Sambuc if (fdl == NULL)
150*11be35a1SLionel Sambuc return (TRUE);
151*11be35a1SLionel Sambuc return (check_bound(fdl, uaddr));
152*11be35a1SLionel Sambuc }
153*11be35a1SLionel Sambuc
154*11be35a1SLionel Sambuc /*
155*11be35a1SLionel Sambuc * Returns NULL if there was some system error.
156*11be35a1SLionel Sambuc * Returns "" if the address was not bound, i.e the server crashed.
157*11be35a1SLionel Sambuc * Returns the merged address otherwise.
158*11be35a1SLionel Sambuc */
159*11be35a1SLionel Sambuc char *
mergeaddr(SVCXPRT * xprt,char * netid,char * uaddr,char * saddr)160*11be35a1SLionel Sambuc mergeaddr(SVCXPRT *xprt, char *netid, char *uaddr, char *saddr)
161*11be35a1SLionel Sambuc {
162*11be35a1SLionel Sambuc struct fdlist *fdl;
163*11be35a1SLionel Sambuc char *c_uaddr, *s_uaddr, *m_uaddr, *allocated_uaddr = NULL;
164*11be35a1SLionel Sambuc
165*11be35a1SLionel Sambuc for (fdl = fdhead; fdl; fdl = fdl->next)
166*11be35a1SLionel Sambuc if (strcmp(fdl->nconf->nc_netid, netid) == 0)
167*11be35a1SLionel Sambuc break;
168*11be35a1SLionel Sambuc if (fdl == NULL)
169*11be35a1SLionel Sambuc return (NULL);
170*11be35a1SLionel Sambuc if (check_bound(fdl, uaddr) == FALSE)
171*11be35a1SLionel Sambuc /* that server died */
172*11be35a1SLionel Sambuc return strdup(emptystring);
173*11be35a1SLionel Sambuc /*
174*11be35a1SLionel Sambuc * If saddr is not NULL, the remote client may have included the
175*11be35a1SLionel Sambuc * address by which it contacted us. Use that for the "client" uaddr,
176*11be35a1SLionel Sambuc * otherwise use the info from the SVCXPRT.
177*11be35a1SLionel Sambuc */
178*11be35a1SLionel Sambuc if (saddr != NULL) {
179*11be35a1SLionel Sambuc c_uaddr = saddr;
180*11be35a1SLionel Sambuc } else {
181*11be35a1SLionel Sambuc c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt));
182*11be35a1SLionel Sambuc if (c_uaddr == NULL) {
183*11be35a1SLionel Sambuc syslog(LOG_ERR, "taddr2uaddr failed for %s",
184*11be35a1SLionel Sambuc fdl->nconf->nc_netid);
185*11be35a1SLionel Sambuc return (NULL);
186*11be35a1SLionel Sambuc }
187*11be35a1SLionel Sambuc allocated_uaddr = c_uaddr;
188*11be35a1SLionel Sambuc }
189*11be35a1SLionel Sambuc
190*11be35a1SLionel Sambuc #ifdef RPCBIND_DEBUG
191*11be35a1SLionel Sambuc if (debugging) {
192*11be35a1SLionel Sambuc if (saddr == NULL) {
193*11be35a1SLionel Sambuc fprintf(stderr, "mergeaddr: client uaddr = %s\n",
194*11be35a1SLionel Sambuc c_uaddr);
195*11be35a1SLionel Sambuc } else {
196*11be35a1SLionel Sambuc fprintf(stderr, "mergeaddr: contact uaddr = %s\n",
197*11be35a1SLionel Sambuc c_uaddr);
198*11be35a1SLionel Sambuc }
199*11be35a1SLionel Sambuc }
200*11be35a1SLionel Sambuc #endif
201*11be35a1SLionel Sambuc s_uaddr = uaddr;
202*11be35a1SLionel Sambuc /*
203*11be35a1SLionel Sambuc * This is all we should need for IP 4 and 6
204*11be35a1SLionel Sambuc */
205*11be35a1SLionel Sambuc m_uaddr = addrmerge(svc_getrpccaller(xprt), s_uaddr, c_uaddr, netid);
206*11be35a1SLionel Sambuc #ifdef RPCBIND_DEBUG
207*11be35a1SLionel Sambuc if (debugging)
208*11be35a1SLionel Sambuc fprintf(stderr, "mergeaddr: uaddr = %s, merged uaddr = %s\n",
209*11be35a1SLionel Sambuc uaddr, m_uaddr);
210*11be35a1SLionel Sambuc #endif
211*11be35a1SLionel Sambuc if (allocated_uaddr != NULL)
212*11be35a1SLionel Sambuc free(allocated_uaddr);
213*11be35a1SLionel Sambuc return (m_uaddr);
214*11be35a1SLionel Sambuc }
215*11be35a1SLionel Sambuc
216*11be35a1SLionel Sambuc /*
217*11be35a1SLionel Sambuc * Returns a netconf structure from its internal list. This
218*11be35a1SLionel Sambuc * structure should not be freed.
219*11be35a1SLionel Sambuc */
220*11be35a1SLionel Sambuc struct netconfig *
rpcbind_get_conf(const char * netid)221*11be35a1SLionel Sambuc rpcbind_get_conf(const char *netid)
222*11be35a1SLionel Sambuc {
223*11be35a1SLionel Sambuc struct fdlist *fdl;
224*11be35a1SLionel Sambuc
225*11be35a1SLionel Sambuc for (fdl = fdhead; fdl; fdl = fdl->next)
226*11be35a1SLionel Sambuc if (strcmp(fdl->nconf->nc_netid, netid) == 0)
227*11be35a1SLionel Sambuc break;
228*11be35a1SLionel Sambuc if (fdl == NULL)
229*11be35a1SLionel Sambuc return (NULL);
230*11be35a1SLionel Sambuc return (fdl->nconf);
231*11be35a1SLionel Sambuc }
232