Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / bsd / am-utils / dist / amd / nfs_prot_svc.c
blobd63ac9a360fc11588ffb0c12465fb6db3beea64f
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 1997-2009 Erez Zadok
5 * Copyright (c) 1989 Jan-Simon Pendry
6 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
7 * Copyright (c) 1989 The Regents of the University of California.
8 * All rights reserved.
10 * This code is derived from software contributed to Berkeley by
11 * Jan-Simon Pendry at Imperial College, London.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgment:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
42 * File: am-utils/amd/nfs_prot_svc.c
46 #ifdef HAVE_CONFIG_H
47 # include <config.h>
48 #endif /* HAVE_CONFIG_H */
49 #include <am_defs.h>
50 #include <amd.h>
52 /* external definitions */
53 extern voidp nfsproc_null_2_svc(voidp, struct svc_req *);
54 extern nfsattrstat *nfsproc_getattr_2_svc(am_nfs_fh *, struct svc_req *);
55 extern nfsattrstat *nfsproc_setattr_2_svc(nfssattrargs *, struct svc_req *);
56 extern voidp nfsproc_root_2_svc(voidp, struct svc_req *);
57 extern nfsdiropres *nfsproc_lookup_2_svc(nfsdiropargs *, struct svc_req *);
58 extern nfsreadlinkres *nfsproc_readlink_2_svc(am_nfs_fh *, struct svc_req *);
59 extern nfsreadres *nfsproc_read_2_svc(nfsreadargs *, struct svc_req *);
60 extern voidp nfsproc_writecache_2_svc(voidp, struct svc_req *);
61 extern nfsattrstat *nfsproc_write_2_svc(nfswriteargs *, struct svc_req *);
62 extern nfsdiropres *nfsproc_create_2_svc(nfscreateargs *, struct svc_req *);
63 extern nfsstat *nfsproc_remove_2_svc(nfsdiropargs *, struct svc_req *);
64 extern nfsstat *nfsproc_rename_2_svc(nfsrenameargs *, struct svc_req *);
65 extern nfsstat *nfsproc_link_2_svc(nfslinkargs *, struct svc_req *);
66 extern nfsstat *nfsproc_symlink_2_svc(nfssymlinkargs *, struct svc_req *);
67 extern nfsdiropres *nfsproc_mkdir_2_svc(nfscreateargs *, struct svc_req *);
68 extern nfsstat *nfsproc_rmdir_2_svc(nfsdiropargs *, struct svc_req *);
69 extern nfsreaddirres *nfsproc_readdir_2_svc(nfsreaddirargs *, struct svc_req *);
70 extern nfsstatfsres *nfsproc_statfs_2_svc(am_nfs_fh *, struct svc_req *);
72 /* global variables */
73 SVCXPRT *current_transp;
75 /* typedefs */
76 typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
79 void
80 nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
82 union {
83 am_nfs_fh nfsproc_getattr_2_arg;
84 nfssattrargs nfsproc_setattr_2_arg;
85 nfsdiropargs nfsproc_lookup_2_arg;
86 am_nfs_fh nfsproc_readlink_2_arg;
87 nfsreadargs nfsproc_read_2_arg;
88 nfswriteargs nfsproc_write_2_arg;
89 nfscreateargs nfsproc_create_2_arg;
90 nfsdiropargs nfsproc_remove_2_arg;
91 nfsrenameargs nfsproc_rename_2_arg;
92 nfslinkargs nfsproc_link_2_arg;
93 nfssymlinkargs nfsproc_symlink_2_arg;
94 nfscreateargs nfsproc_mkdir_2_arg;
95 nfsdiropargs fsproc_rmdir_2_arg;
96 nfsreaddirargs nfsproc_readdir_2_arg;
97 am_nfs_fh nfsproc_statfs_2_arg;
98 } argument;
99 char *result;
100 xdrproc_t xdr_argument, xdr_result;
101 nfssvcproc_t local;
103 #ifdef HAVE_TRANSPORT_TYPE_TLI
105 * On TLI systems we don't use an INET network type, but a "ticlts" (see
106 * /etc/netconfig and conf/transp_tli.c:create_nfs_service). This means
107 * that packets could only come from the loopback interface, and we don't
108 * need to check them and filter possibly spoofed packets. Therefore we
109 * only need to check if the UID caller is correct.
111 # ifdef HAVE___RPC_GET_LOCAL_UID
112 uid_t u;
113 /* extern definition for an internal libnsl function */
114 extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid);
115 if (__rpc_get_local_uid(transp, &u) >= 0 && u != 0) {
116 plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u);
117 return;
119 # else /* not HAVE___RPC_GET_LOCAL_UID */
120 dlog("cannot verify local uid for rpc request");
121 # endif /* HAVE___RPC_GET_LOCAL_UID */
122 #else /* not HAVE_TRANPORT_TYPE_TLI */
123 struct sockaddr_in *sinp;
124 char dq[20], dq2[28];
125 sinp = amu_svc_getcaller(rqstp->rq_xprt);
126 # ifdef MNT2_NFS_OPT_RESVPORT
127 /* Verify that the request comes from a reserved port */
128 if (sinp &&
129 ntohs(sinp->sin_port) >= IPPORT_RESERVED &&
130 !(gopt.flags & CFM_NFS_INSECURE_PORT)) {
131 plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved",
132 inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
133 ntohs(sinp->sin_port));
134 return;
136 # endif /* MNT2_NFS_OPT_RESVPORT */
137 /* if the address does not match, ignore the request */
138 if (sinp && (sinp->sin_addr.s_addr != myipaddr.s_addr)) {
139 if (gopt.flags & CFM_NFS_ANY_INTERFACE) {
140 if (!is_interface_local(sinp->sin_addr.s_addr)) {
141 plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface",
142 inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
143 ntohs(sinp->sin_port));
145 } else {
146 plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
147 inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
148 ntohs(sinp->sin_port),
149 inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
150 return;
153 #endif /* not HAVE_TRANPORT_TYPE_TLI */
155 current_transp = NULL;
157 switch (rqstp->rq_proc) {
159 case NFSPROC_NULL:
160 xdr_argument = (xdrproc_t) xdr_void;
161 xdr_result = (xdrproc_t) xdr_void;
162 local = (nfssvcproc_t) nfsproc_null_2_svc;
163 break;
165 case NFSPROC_GETATTR:
166 xdr_argument = (xdrproc_t) xdr_nfs_fh;
167 xdr_result = (xdrproc_t) xdr_attrstat;
168 local = (nfssvcproc_t) nfsproc_getattr_2_svc;
169 break;
171 case NFSPROC_SETATTR:
172 xdr_argument = (xdrproc_t) xdr_sattrargs;
173 xdr_result = (xdrproc_t) xdr_attrstat;
174 local = (nfssvcproc_t) nfsproc_setattr_2_svc;
175 break;
177 case NFSPROC_ROOT:
178 xdr_argument = (xdrproc_t) xdr_void;
179 xdr_result = (xdrproc_t) xdr_void;
180 local = (nfssvcproc_t) nfsproc_root_2_svc;
181 break;
183 case NFSPROC_LOOKUP:
184 xdr_argument = (xdrproc_t) xdr_diropargs;
185 xdr_result = (xdrproc_t) xdr_diropres;
186 local = (nfssvcproc_t) nfsproc_lookup_2_svc;
188 * Cheap way to pass transp down to amfs_auto_lookuppn so it can
189 * be stored in the am_node structure and later used for
190 * quick_reply().
192 current_transp = transp;
193 break;
195 case NFSPROC_READLINK:
196 xdr_argument = (xdrproc_t) xdr_nfs_fh;
197 xdr_result = (xdrproc_t) xdr_readlinkres;
198 local = (nfssvcproc_t) nfsproc_readlink_2_svc;
199 break;
201 case NFSPROC_READ:
202 xdr_argument = (xdrproc_t) xdr_readargs;
203 xdr_result = (xdrproc_t) xdr_readres;
204 local = (nfssvcproc_t) nfsproc_read_2_svc;
205 break;
207 case NFSPROC_WRITECACHE:
208 xdr_argument = (xdrproc_t) xdr_void;
209 xdr_result = (xdrproc_t) xdr_void;
210 local = (nfssvcproc_t) nfsproc_writecache_2_svc;
211 break;
213 case NFSPROC_WRITE:
214 xdr_argument = (xdrproc_t) xdr_writeargs;
215 xdr_result = (xdrproc_t) xdr_attrstat;
216 local = (nfssvcproc_t) nfsproc_write_2_svc;
217 break;
219 case NFSPROC_CREATE:
220 xdr_argument = (xdrproc_t) xdr_createargs;
221 xdr_result = (xdrproc_t) xdr_diropres;
222 local = (nfssvcproc_t) nfsproc_create_2_svc;
223 break;
225 case NFSPROC_REMOVE:
226 xdr_argument = (xdrproc_t) xdr_diropargs;
227 xdr_result = (xdrproc_t) xdr_nfsstat;
228 local = (nfssvcproc_t) nfsproc_remove_2_svc;
229 break;
231 case NFSPROC_RENAME:
232 xdr_argument = (xdrproc_t) xdr_renameargs;
233 xdr_result = (xdrproc_t) xdr_nfsstat;
234 local = (nfssvcproc_t) nfsproc_rename_2_svc;
235 break;
237 case NFSPROC_LINK:
238 xdr_argument = (xdrproc_t) xdr_linkargs;
239 xdr_result = (xdrproc_t) xdr_nfsstat;
240 local = (nfssvcproc_t) nfsproc_link_2_svc;
241 break;
243 case NFSPROC_SYMLINK:
244 xdr_argument = (xdrproc_t) xdr_symlinkargs;
245 xdr_result = (xdrproc_t) xdr_nfsstat;
246 local = (nfssvcproc_t) nfsproc_symlink_2_svc;
247 break;
249 case NFSPROC_MKDIR:
250 xdr_argument = (xdrproc_t) xdr_createargs;
251 xdr_result = (xdrproc_t) xdr_diropres;
252 local = (nfssvcproc_t) nfsproc_mkdir_2_svc;
253 break;
255 case NFSPROC_RMDIR:
256 xdr_argument = (xdrproc_t) xdr_diropargs;
257 xdr_result = (xdrproc_t) xdr_nfsstat;
258 local = (nfssvcproc_t) nfsproc_rmdir_2_svc;
259 break;
261 case NFSPROC_READDIR:
262 xdr_argument = (xdrproc_t) xdr_readdirargs;
263 xdr_result = (xdrproc_t) xdr_readdirres;
264 local = (nfssvcproc_t) nfsproc_readdir_2_svc;
265 break;
267 case NFSPROC_STATFS:
268 xdr_argument = (xdrproc_t) xdr_nfs_fh;
269 xdr_result = (xdrproc_t) xdr_statfsres;
270 local = (nfssvcproc_t) nfsproc_statfs_2_svc;
271 break;
273 default:
274 svcerr_noproc(transp);
275 return;
278 memset((char *) &argument, 0, sizeof(argument));
279 if (!svc_getargs(transp,
280 (XDRPROC_T_TYPE) xdr_argument,
281 (SVC_IN_ARG_TYPE) &argument)) {
282 plog(XLOG_ERROR,
283 "NFS xdr decode failed for %d %d %d",
284 (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
285 svcerr_decode(transp);
286 return;
288 result = (*local) (&argument, rqstp);
290 current_transp = NULL;
292 if (result != NULL && !svc_sendreply(transp,
293 (XDRPROC_T_TYPE) xdr_result,
294 result)) {
295 svcerr_systemerr(transp);
297 if (!svc_freeargs(transp,
298 (XDRPROC_T_TYPE) xdr_argument,
299 (SVC_IN_ARG_TYPE) & argument)) {
300 plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_2");
301 going_down(1);