xref: /dragonfly/usr.sbin/rpcbind/rpcb_svc.c (revision bd91f5c31d05935d34ffa5befc63a95350bbf000)
1 /*
2  * Copyright (c) 2009, Sun Microsystems, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * - Redistributions of source code must retain the above copyright notice,
8  *   this list of conditions and the following disclaimer.
9  * - Redistributions in binary form must reproduce the above copyright notice,
10  *   this list of conditions and the following disclaimer in the documentation
11  *   and/or other materials provided with the distribution.
12  * - Neither the name of Sun Microsystems, Inc. nor the names of its
13  *   contributors may be used to endorse or promote products derived
14  *   from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  *
28  * @(#)rpcb_svc.c   1.16      93/07/05 SMI"
29  * $NetBSD: rpcb_svc.c,v 1.1 2000/06/02 23:15:41 fvdl Exp $
30  * $FreeBSD: src/usr.sbin/rpcbind/rpcb_svc.c,v 1.3 2007/11/07 10:53:39 kevlo Exp $
31  */
32 /*
33  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
34  */
35 
36 /*
37  * rpcb_svc.c
38  * The server procedure for the version 3 rpcbind (TLI).
39  *
40  * It maintains a separate list of all the registered services with the
41  * version 3 of rpcbind.
42  */
43 #include <sys/types.h>
44 #include <rpc/rpc.h>
45 #include <rpc/rpcb_prot.h>
46 #include <netconfig.h>
47 #include <syslog.h>
48 #include <stdlib.h>
49 #include <stdio.h>
50 #include <string.h>
51 
52 #include "rpcbind.h"
53 
54 static void         *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *,
55                                                     rpcvers_t);
56 static void         *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *,
57                                                rpcvers_t);
58 
59 /*
60  * Called by svc_getreqset. There is a separate server handle for
61  * every transport that it waits on.
62  */
63 void
rpcb_service_3(struct svc_req * rqstp,SVCXPRT * transp)64 rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp)
65 {
66           union {
67                     RPCB rpcbproc_set_3_arg;
68                     RPCB rpcbproc_unset_3_arg;
69                     RPCB rpcbproc_getaddr_3_local_arg;
70                     struct rpcb_rmtcallargs rpcbproc_callit_3_arg;
71                     char *rpcbproc_uaddr2taddr_3_arg;
72                     struct netbuf rpcbproc_taddr2uaddr_3_arg;
73           } argument;
74           char *result;
75           xdrproc_t xdr_argument, xdr_result;
76           void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
77 
78           rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc);
79 
80           switch (rqstp->rq_proc) {
81           case NULLPROC:
82                     /*
83                      * Null proc call
84                      */
85 #ifdef RPCBIND_DEBUG
86                     if (debugging)
87                               fprintf(stderr, "RPCBPROC_NULL\n");
88 #endif
89                     /* This call just logs, no actual checks */
90                     check_access(transp, rqstp->rq_proc, NULL, RPCBVERS);
91                     svc_sendreply(transp, (xdrproc_t)xdr_void, NULL);
92                     return;
93 
94           case RPCBPROC_SET:
95                     xdr_argument = (xdrproc_t )xdr_rpcb;
96                     xdr_result = (xdrproc_t )xdr_bool;
97                     local = rpcbproc_set_com;
98                     break;
99 
100           case RPCBPROC_UNSET:
101                     xdr_argument = (xdrproc_t)xdr_rpcb;
102                     xdr_result = (xdrproc_t)xdr_bool;
103                     local = rpcbproc_unset_com;
104                     break;
105 
106           case RPCBPROC_GETADDR:
107                     xdr_argument = (xdrproc_t)xdr_rpcb;
108                     xdr_result = (xdrproc_t)xdr_wrapstring;
109                     local = rpcbproc_getaddr_3_local;
110                     break;
111 
112           case RPCBPROC_DUMP:
113 #ifdef RPCBIND_DEBUG
114                     if (debugging)
115                               fprintf(stderr, "RPCBPROC_DUMP\n");
116 #endif
117                     xdr_argument = (xdrproc_t)xdr_void;
118                     xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
119                     local = rpcbproc_dump_3_local;
120                     break;
121 
122           case RPCBPROC_CALLIT:
123                     rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS);
124                     return;
125 
126           case RPCBPROC_GETTIME:
127 #ifdef RPCBIND_DEBUG
128                     if (debugging)
129                               fprintf(stderr, "RPCBPROC_GETTIME\n");
130 #endif
131                     xdr_argument = (xdrproc_t)xdr_void;
132                     xdr_result = (xdrproc_t)xdr_u_long;
133                     local = rpcbproc_gettime_com;
134                     break;
135 
136           case RPCBPROC_UADDR2TADDR:
137 #ifdef RPCBIND_DEBUG
138                     if (debugging)
139                               fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
140 #endif
141                     xdr_argument = (xdrproc_t)xdr_wrapstring;
142                     xdr_result = (xdrproc_t)xdr_netbuf;
143                     local = rpcbproc_uaddr2taddr_com;
144                     break;
145 
146           case RPCBPROC_TADDR2UADDR:
147 #ifdef RPCBIND_DEBUG
148                     if (debugging)
149                               fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
150 #endif
151                     xdr_argument = (xdrproc_t)xdr_netbuf;
152                     xdr_result = (xdrproc_t)xdr_wrapstring;
153                     local = rpcbproc_taddr2uaddr_com;
154                     break;
155 
156           default:
157                     svcerr_noproc(transp);
158                     return;
159           }
160           memset((char *)&argument, 0, sizeof (argument));
161           if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
162                                         (char *) &argument)) {
163                     svcerr_decode(transp);
164                     if (debugging)
165                               fprintf(stderr, "rpcbind: could not decode\n");
166                     return;
167           }
168           if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) {
169                     svcerr_weakauth(transp);
170                     goto done;
171           }
172           result = (*local)(&argument, rqstp, transp, RPCBVERS);
173           if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result,
174                                                             result)) {
175                     svcerr_systemerr(transp);
176                     if (debugging) {
177                               fprintf(stderr, "rpcbind: svc_sendreply\n");
178                               if (doabort) {
179                                         rpcbind_abort();
180                               }
181                     }
182           }
183 done:
184           if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)
185                                         &argument)) {
186                     if (debugging) {
187                               fprintf(stderr, "unable to free arguments\n");
188                               if (doabort) {
189                                         rpcbind_abort();
190                               }
191                     }
192           }
193 }
194 
195 /*
196  * Lookup the mapping for a program, version and return its
197  * address. Assuming that the caller wants the address of the
198  * server running on the transport on which the request came.
199  *
200  * We also try to resolve the universal address in terms of
201  * address of the caller.
202  */
203 /* ARGSUSED */
204 static void *
rpcbproc_getaddr_3_local(void * arg,struct svc_req * rqstp __unused,SVCXPRT * transp __unused,rpcvers_t versnum __unused)205 rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp __unused,
206                                SVCXPRT *transp __unused, rpcvers_t versnum __unused)
207 {
208           RPCB *regp = (RPCB *)arg;
209 #ifdef RPCBIND_DEBUG
210           if (debugging) {
211                     char *uaddr;
212 
213                     uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
214                                   svc_getrpccaller(transp));
215                     fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
216                         (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
217                         regp->r_netid, uaddr);
218                     free(uaddr);
219           }
220 #endif
221           return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS,
222               RPCB_ALLVERS));
223 }
224 
225 /* ARGSUSED */
226 static void *
rpcbproc_dump_3_local(void * arg __unused,struct svc_req * rqstp __unused,SVCXPRT * transp __unused,rpcvers_t versnum __unused)227 rpcbproc_dump_3_local(void *arg __unused, struct svc_req *rqstp __unused,
228                           SVCXPRT *transp __unused, rpcvers_t versnum __unused)
229 {
230           return ((void *)&list_rbl);
231 }
232