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.
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
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
42 * File: am-utils/amd/nfs_prot_svc.c
48 #endif /* HAVE_CONFIG_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
;
76 typedef char *(*nfssvcproc_t
)(voidp
, struct svc_req
*);
80 nfs_program_2(struct svc_req
*rqstp
, SVCXPRT
*transp
)
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
;
100 xdrproc_t xdr_argument
, xdr_result
;
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
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
);
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 */
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
));
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
));
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
));
153 #endif /* not HAVE_TRANPORT_TYPE_TLI */
155 current_transp
= NULL
;
157 switch (rqstp
->rq_proc
) {
160 xdr_argument
= (xdrproc_t
) xdr_void
;
161 xdr_result
= (xdrproc_t
) xdr_void
;
162 local
= (nfssvcproc_t
) nfsproc_null_2_svc
;
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
;
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
;
178 xdr_argument
= (xdrproc_t
) xdr_void
;
179 xdr_result
= (xdrproc_t
) xdr_void
;
180 local
= (nfssvcproc_t
) nfsproc_root_2_svc
;
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
192 current_transp
= transp
;
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
;
202 xdr_argument
= (xdrproc_t
) xdr_readargs
;
203 xdr_result
= (xdrproc_t
) xdr_readres
;
204 local
= (nfssvcproc_t
) nfsproc_read_2_svc
;
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
;
214 xdr_argument
= (xdrproc_t
) xdr_writeargs
;
215 xdr_result
= (xdrproc_t
) xdr_attrstat
;
216 local
= (nfssvcproc_t
) nfsproc_write_2_svc
;
220 xdr_argument
= (xdrproc_t
) xdr_createargs
;
221 xdr_result
= (xdrproc_t
) xdr_diropres
;
222 local
= (nfssvcproc_t
) nfsproc_create_2_svc
;
226 xdr_argument
= (xdrproc_t
) xdr_diropargs
;
227 xdr_result
= (xdrproc_t
) xdr_nfsstat
;
228 local
= (nfssvcproc_t
) nfsproc_remove_2_svc
;
232 xdr_argument
= (xdrproc_t
) xdr_renameargs
;
233 xdr_result
= (xdrproc_t
) xdr_nfsstat
;
234 local
= (nfssvcproc_t
) nfsproc_rename_2_svc
;
238 xdr_argument
= (xdrproc_t
) xdr_linkargs
;
239 xdr_result
= (xdrproc_t
) xdr_nfsstat
;
240 local
= (nfssvcproc_t
) nfsproc_link_2_svc
;
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
;
250 xdr_argument
= (xdrproc_t
) xdr_createargs
;
251 xdr_result
= (xdrproc_t
) xdr_diropres
;
252 local
= (nfssvcproc_t
) nfsproc_mkdir_2_svc
;
256 xdr_argument
= (xdrproc_t
) xdr_diropargs
;
257 xdr_result
= (xdrproc_t
) xdr_nfsstat
;
258 local
= (nfssvcproc_t
) nfsproc_rmdir_2_svc
;
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
;
268 xdr_argument
= (xdrproc_t
) xdr_nfs_fh
;
269 xdr_result
= (xdrproc_t
) xdr_statfsres
;
270 local
= (nfssvcproc_t
) nfsproc_statfs_2_svc
;
274 svcerr_noproc(transp
);
278 memset((char *) &argument
, 0, sizeof(argument
));
279 if (!svc_getargs(transp
,
280 (XDRPROC_T_TYPE
) xdr_argument
,
281 (SVC_IN_ARG_TYPE
) &argument
)) {
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
);
288 result
= (*local
) (&argument
, rqstp
);
290 current_transp
= NULL
;
292 if (result
!= NULL
&& !svc_sendreply(transp
,
293 (XDRPROC_T_TYPE
) xdr_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");