1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
28 */
29 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
30 /* All Rights Reserved */
31 /*
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
34 * All Rights Reserved
35 *
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
39 */
40
41 /*
42 * rpcb_svc.c
43 * The server procedure for the version 3 rpcbind (TLI).
44 *
45 * It maintains a separate list of all the registered services with the
46 * version 3 of rpcbind.
47 */
48 #include <stdio.h>
49 #include <strings.h>
50 #include <sys/types.h>
51 #include <rpc/rpc.h>
52 #include <rpc/rpcb_prot.h>
53 #include <netconfig.h>
54 #include <syslog.h>
55 #include <netdir.h>
56 #include <stdlib.h>
57 #include "rpcbind.h"
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_arg;
70 rpcb_rmtcallargs rpcbproc_callit_3_arg;
71 char *rpcbproc_uaddr2taddr_3_arg;
72 struct netbuf rpcbproc_taddr2uaddr_3_arg;
73 } argument;
74 union {
75 bool_t rpcbproc_set_3_res;
76 bool_t rpcbproc_unset_3_res;
77 char *rpcbproc_getaddr_3_res;
78 rpcblist_ptr *rpcbproc_dump_3_res;
79 ulong_t rpcbproc_gettime_3_res;
80 struct netbuf rpcbproc_uaddr2taddr_3_res;
81 char *rpcbproc_taddr2uaddr_3_res;
82 } result;
83 bool_t retval;
84 xdrproc_t xdr_argument, xdr_result;
85 bool_t (*local)();
86
87 rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc);
88
89 RPCB_CHECK(transp, rqstp->rq_proc);
90
91 switch (rqstp->rq_proc) {
92 case NULLPROC:
93 /*
94 * Null proc call
95 */
96 (void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
97 return;
98
99 case RPCBPROC_SET:
100 /*
101 * Check to see whether the message came from
102 * loopback transports (for security reasons)
103 */
104 if (strcasecmp(transp->xp_netid, loopback_dg) &&
105 strcasecmp(transp->xp_netid, loopback_vc) &&
106 strcasecmp(transp->xp_netid, loopback_vc_ord)) {
107 char *uaddr;
108
109 uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
110 svc_getrpccaller(transp));
111 syslog(LOG_ERR, "non-local attempt to set from %s",
112 uaddr == NULL ? "<unknown>" : uaddr);
113 free(uaddr);
114 svcerr_weakauth(transp);
115 return;
116 }
117 xdr_argument = xdr_rpcb;
118 xdr_result = xdr_bool;
119 local = (bool_t (*)()) rpcbproc_set_com;
120 break;
121
122 case RPCBPROC_UNSET:
123 /*
124 * Check to see whether the message came from
125 * loopback transports (for security reasons)
126 */
127 if (strcasecmp(transp->xp_netid, loopback_dg) &&
128 strcasecmp(transp->xp_netid, loopback_vc) &&
129 strcasecmp(transp->xp_netid, loopback_vc_ord)) {
130 char *uaddr;
131
132 uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
133 svc_getrpccaller(transp));
134 syslog(LOG_ERR, "non-local attempt to unset from %s",
135 uaddr == NULL ? "<unknown>" : uaddr);
136 free(uaddr);
137 svcerr_weakauth(transp);
138 return;
139 }
140 xdr_argument = xdr_rpcb;
141 xdr_result = xdr_bool;
142 local = (bool_t (*)()) rpcbproc_unset_com;
143 break;
144
145 case RPCBPROC_GETADDR:
146 xdr_argument = xdr_rpcb;
147 xdr_result = xdr_wrapstring;
148 local = (bool_t (*)()) rpcbproc_getaddr_com;
149 break;
150
151 case RPCBPROC_DUMP:
152 xdr_argument = xdr_void;
153 xdr_result = xdr_rpcblist_ptr_ptr;
154 local = (bool_t (*)()) rpcbproc_dump_com;
155 break;
156
157 case RPCBPROC_CALLIT:
158 rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS);
159 return;
160
161 case RPCBPROC_GETTIME:
162 xdr_argument = xdr_void;
163 xdr_result = xdr_u_long;
164 local = (bool_t (*)()) rpcbproc_gettime_com;
165 break;
166
167 case RPCBPROC_UADDR2TADDR:
168 xdr_argument = xdr_wrapstring;
169 xdr_result = xdr_netbuf;
170 local = (bool_t (*)()) rpcbproc_uaddr2taddr_com;
171 break;
172
173 case RPCBPROC_TADDR2UADDR:
174 xdr_argument = xdr_netbuf;
175 xdr_result = xdr_wrapstring;
176 local = (bool_t (*)()) rpcbproc_taddr2uaddr_com;
177 break;
178
179 default:
180 svcerr_noproc(transp);
181 return;
182 }
183 (void) memset((char *)&argument, 0, sizeof (argument));
184 if (!svc_getargs(transp, xdr_argument, (char *)&argument)) {
185 svcerr_decode(transp);
186 if (debugging)
187 (void) fprintf(stderr, "rpcbind: could not decode\n");
188 return;
189 }
190 retval = (*local)(&argument, &result, rqstp, RPCBVERS);
191 if (retval > 0 && !svc_sendreply(transp, xdr_result, (char *)&result)) {
192 svcerr_systemerr(transp);
193 if (debugging) {
194 (void) fprintf(stderr, "rpcbind: svc_sendreply\n");
195 if (doabort) {
196 rpcbind_abort();
197 }
198 }
199 }
200 if (!svc_freeargs(transp, xdr_argument, (char *)&argument)) {
201 if (debugging) {
202 (void) fprintf(stderr, "unable to free arguments\n");
203 if (doabort) {
204 rpcbind_abort();
205 }
206 }
207 }
208
209 xdr_free(xdr_result, (char *)&result);
210 }
211