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