xref: /minix3/tests/fs/nfs/nfsservice/rpcbind/check_bound.c (revision 11be35a165022172ed3cea20f2b5df0307540b0e)
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