1 /* $NetBSD: nfs_prot_svc.c,v 1.1.1.3 2015/01/17 16:34:15 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1997-2014 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. 9 * 10 * This code is derived from software contributed to Berkeley by 11 * Jan-Simon Pendry at Imperial College, London. 12 * 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. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * 38 * File: am-utils/amd/nfs_prot_svc.c 39 * 40 */ 41 42 #ifdef HAVE_CONFIG_H 43 # include <config.h> 44 #endif /* HAVE_CONFIG_H */ 45 #include <am_defs.h> 46 #include <amd.h> 47 48 /* external definitions */ 49 extern voidp nfsproc_null_2_svc(voidp, struct svc_req *); 50 extern nfsattrstat *nfsproc_getattr_2_svc(am_nfs_fh *, struct svc_req *); 51 extern nfsattrstat *nfsproc_setattr_2_svc(nfssattrargs *, struct svc_req *); 52 extern voidp nfsproc_root_2_svc(voidp, struct svc_req *); 53 extern nfsdiropres *nfsproc_lookup_2_svc(nfsdiropargs *, struct svc_req *); 54 extern nfsreadlinkres *nfsproc_readlink_2_svc(am_nfs_fh *, struct svc_req *); 55 extern nfsreadres *nfsproc_read_2_svc(nfsreadargs *, struct svc_req *); 56 extern voidp nfsproc_writecache_2_svc(voidp, struct svc_req *); 57 extern nfsattrstat *nfsproc_write_2_svc(nfswriteargs *, struct svc_req *); 58 extern nfsdiropres *nfsproc_create_2_svc(nfscreateargs *, struct svc_req *); 59 extern nfsstat *nfsproc_remove_2_svc(nfsdiropargs *, struct svc_req *); 60 extern nfsstat *nfsproc_rename_2_svc(nfsrenameargs *, struct svc_req *); 61 extern nfsstat *nfsproc_link_2_svc(nfslinkargs *, struct svc_req *); 62 extern nfsstat *nfsproc_symlink_2_svc(nfssymlinkargs *, struct svc_req *); 63 extern nfsdiropres *nfsproc_mkdir_2_svc(nfscreateargs *, struct svc_req *); 64 extern nfsstat *nfsproc_rmdir_2_svc(nfsdiropargs *, struct svc_req *); 65 extern nfsreaddirres *nfsproc_readdir_2_svc(nfsreaddirargs *, struct svc_req *); 66 extern nfsstatfsres *nfsproc_statfs_2_svc(am_nfs_fh *, struct svc_req *); 67 68 /* global variables */ 69 SVCXPRT *current_transp; 70 dispatcher_t nfs_dispatcher = nfs_program_2; 71 72 /* typedefs */ 73 typedef char *(*nfssvcproc_t)(voidp, struct svc_req *); 74 75 76 void 77 nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp) 78 { 79 union { 80 am_nfs_fh nfsproc_getattr_2_arg; 81 nfssattrargs nfsproc_setattr_2_arg; 82 nfsdiropargs nfsproc_lookup_2_arg; 83 am_nfs_fh nfsproc_readlink_2_arg; 84 nfsreadargs nfsproc_read_2_arg; 85 nfswriteargs nfsproc_write_2_arg; 86 nfscreateargs nfsproc_create_2_arg; 87 nfsdiropargs nfsproc_remove_2_arg; 88 nfsrenameargs nfsproc_rename_2_arg; 89 nfslinkargs nfsproc_link_2_arg; 90 nfssymlinkargs nfsproc_symlink_2_arg; 91 nfscreateargs nfsproc_mkdir_2_arg; 92 nfsdiropargs fsproc_rmdir_2_arg; 93 nfsreaddirargs nfsproc_readdir_2_arg; 94 am_nfs_fh nfsproc_statfs_2_arg; 95 } argument; 96 char *result; 97 xdrproc_t xdr_argument, xdr_result; 98 nfssvcproc_t local; 99 100 #ifdef HAVE_TRANSPORT_TYPE_TLI 101 /* 102 * On TLI systems we don't use an INET network type, but a "ticlts" (see 103 * /etc/netconfig and conf/transp_tli.c:create_nfs_service). This means 104 * that packets could only come from the loopback interface, and we don't 105 * need to check them and filter possibly spoofed packets. Therefore we 106 * only need to check if the UID caller is correct. 107 */ 108 # ifdef HAVE___RPC_GET_LOCAL_UID 109 uid_t u; 110 /* extern definition for an internal libnsl function */ 111 extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid); 112 if (__rpc_get_local_uid(transp, &u) >= 0 && u != 0) { 113 plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u); 114 return; 115 } 116 # else /* not HAVE___RPC_GET_LOCAL_UID */ 117 dlog("cannot verify local uid for rpc request"); 118 # endif /* HAVE___RPC_GET_LOCAL_UID */ 119 #else /* not HAVE_TRANPORT_TYPE_TLI */ 120 struct sockaddr_in *sinp; 121 char dq[20], dq2[28]; 122 sinp = amu_svc_getcaller(rqstp->rq_xprt); 123 # ifdef MNT2_NFS_OPT_RESVPORT 124 /* Verify that the request comes from a reserved port */ 125 if (sinp && 126 ntohs(sinp->sin_port) >= IPPORT_RESERVED && 127 !(gopt.flags & CFM_NFS_INSECURE_PORT)) { 128 plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved", 129 inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr), 130 ntohs(sinp->sin_port)); 131 return; 132 } 133 # endif /* MNT2_NFS_OPT_RESVPORT */ 134 /* if the address does not match, ignore the request */ 135 if (sinp && (sinp->sin_addr.s_addr != myipaddr.s_addr)) { 136 if (gopt.flags & CFM_NFS_ANY_INTERFACE) { 137 if (!is_interface_local(sinp->sin_addr.s_addr)) { 138 plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface", 139 inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr), 140 ntohs(sinp->sin_port)); 141 } 142 } else { 143 plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s", 144 inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr), 145 ntohs(sinp->sin_port), 146 inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr)); 147 return; 148 } 149 } 150 #endif /* not HAVE_TRANPORT_TYPE_TLI */ 151 152 current_transp = NULL; 153 154 switch (rqstp->rq_proc) { 155 156 case NFSPROC_NULL: 157 xdr_argument = (xdrproc_t) xdr_void; 158 xdr_result = (xdrproc_t) xdr_void; 159 local = (nfssvcproc_t) nfsproc_null_2_svc; 160 break; 161 162 case NFSPROC_GETATTR: 163 xdr_argument = (xdrproc_t) xdr_nfs_fh; 164 xdr_result = (xdrproc_t) xdr_attrstat; 165 local = (nfssvcproc_t) nfsproc_getattr_2_svc; 166 break; 167 168 case NFSPROC_SETATTR: 169 xdr_argument = (xdrproc_t) xdr_sattrargs; 170 xdr_result = (xdrproc_t) xdr_attrstat; 171 local = (nfssvcproc_t) nfsproc_setattr_2_svc; 172 break; 173 174 case NFSPROC_ROOT: 175 xdr_argument = (xdrproc_t) xdr_void; 176 xdr_result = (xdrproc_t) xdr_void; 177 local = (nfssvcproc_t) nfsproc_root_2_svc; 178 break; 179 180 case NFSPROC_LOOKUP: 181 xdr_argument = (xdrproc_t) xdr_diropargs; 182 xdr_result = (xdrproc_t) xdr_diropres; 183 local = (nfssvcproc_t) nfsproc_lookup_2_svc; 184 /* 185 * Cheap way to pass transp down to amfs_auto_lookuppn so it can 186 * be stored in the am_node structure and later used for 187 * quick_reply(). 188 */ 189 current_transp = transp; 190 break; 191 192 case NFSPROC_READLINK: 193 xdr_argument = (xdrproc_t) xdr_nfs_fh; 194 xdr_result = (xdrproc_t) xdr_readlinkres; 195 local = (nfssvcproc_t) nfsproc_readlink_2_svc; 196 break; 197 198 case NFSPROC_READ: 199 xdr_argument = (xdrproc_t) xdr_readargs; 200 xdr_result = (xdrproc_t) xdr_readres; 201 local = (nfssvcproc_t) nfsproc_read_2_svc; 202 break; 203 204 case NFSPROC_WRITECACHE: 205 xdr_argument = (xdrproc_t) xdr_void; 206 xdr_result = (xdrproc_t) xdr_void; 207 local = (nfssvcproc_t) nfsproc_writecache_2_svc; 208 break; 209 210 case NFSPROC_WRITE: 211 xdr_argument = (xdrproc_t) xdr_writeargs; 212 xdr_result = (xdrproc_t) xdr_attrstat; 213 local = (nfssvcproc_t) nfsproc_write_2_svc; 214 break; 215 216 case NFSPROC_CREATE: 217 xdr_argument = (xdrproc_t) xdr_createargs; 218 xdr_result = (xdrproc_t) xdr_diropres; 219 local = (nfssvcproc_t) nfsproc_create_2_svc; 220 break; 221 222 case NFSPROC_REMOVE: 223 xdr_argument = (xdrproc_t) xdr_diropargs; 224 xdr_result = (xdrproc_t) xdr_nfsstat; 225 local = (nfssvcproc_t) nfsproc_remove_2_svc; 226 break; 227 228 case NFSPROC_RENAME: 229 xdr_argument = (xdrproc_t) xdr_renameargs; 230 xdr_result = (xdrproc_t) xdr_nfsstat; 231 local = (nfssvcproc_t) nfsproc_rename_2_svc; 232 break; 233 234 case NFSPROC_LINK: 235 xdr_argument = (xdrproc_t) xdr_linkargs; 236 xdr_result = (xdrproc_t) xdr_nfsstat; 237 local = (nfssvcproc_t) nfsproc_link_2_svc; 238 break; 239 240 case NFSPROC_SYMLINK: 241 xdr_argument = (xdrproc_t) xdr_symlinkargs; 242 xdr_result = (xdrproc_t) xdr_nfsstat; 243 local = (nfssvcproc_t) nfsproc_symlink_2_svc; 244 break; 245 246 case NFSPROC_MKDIR: 247 xdr_argument = (xdrproc_t) xdr_createargs; 248 xdr_result = (xdrproc_t) xdr_diropres; 249 local = (nfssvcproc_t) nfsproc_mkdir_2_svc; 250 break; 251 252 case NFSPROC_RMDIR: 253 xdr_argument = (xdrproc_t) xdr_diropargs; 254 xdr_result = (xdrproc_t) xdr_nfsstat; 255 local = (nfssvcproc_t) nfsproc_rmdir_2_svc; 256 break; 257 258 case NFSPROC_READDIR: 259 xdr_argument = (xdrproc_t) xdr_readdirargs; 260 xdr_result = (xdrproc_t) xdr_readdirres; 261 local = (nfssvcproc_t) nfsproc_readdir_2_svc; 262 break; 263 264 case NFSPROC_STATFS: 265 xdr_argument = (xdrproc_t) xdr_nfs_fh; 266 xdr_result = (xdrproc_t) xdr_statfsres; 267 local = (nfssvcproc_t) nfsproc_statfs_2_svc; 268 break; 269 270 default: 271 svcerr_noproc(transp); 272 return; 273 } 274 275 memset((char *) &argument, 0, sizeof(argument)); 276 if (!svc_getargs(transp, 277 (XDRPROC_T_TYPE) xdr_argument, 278 (SVC_IN_ARG_TYPE) &argument)) { 279 plog(XLOG_ERROR, 280 "NFS xdr decode failed for %d %d %d", 281 (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc); 282 svcerr_decode(transp); 283 return; 284 } 285 result = (*local) (&argument, rqstp); 286 287 current_transp = NULL; 288 289 if (result != NULL && !svc_sendreply(transp, 290 (XDRPROC_T_TYPE) xdr_result, 291 result)) { 292 svcerr_systemerr(transp); 293 } 294 if (!svc_freeargs(transp, 295 (XDRPROC_T_TYPE) xdr_argument, 296 (SVC_IN_ARG_TYPE) & argument)) { 297 plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_2"); 298 going_down(1); 299 } 300 } 301 302 void 303 nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp) 304 { 305 union { 306 am_GETATTR3args am_nfs3_getattr_3_arg; 307 am_SETATTR3args am_nfs3_setattr_3_arg; 308 am_LOOKUP3args am_nfs3_lookup_3_arg; 309 am_ACCESS3args am_nfs3_access_3_arg; 310 am_READLINK3args am_nfs3_readlink_3_arg; 311 am_READ3args am_nfs3_read_3_arg; 312 am_WRITE3args am_nfs3_write_3_arg; 313 am_CREATE3args am_nfs3_create_3_arg; 314 am_MKDIR3args am_nfs3_mkdir_3_arg; 315 am_SYMLINK3args am_nfs3_symlink_3_arg; 316 am_MKNOD3args am_nfs3_mknod_3_arg; 317 am_REMOVE3args am_nfs3_remove_3_arg; 318 am_RMDIR3args am_nfs3_rmdir_3_arg; 319 am_RENAME3args am_nfs3_rename_3_arg; 320 am_LINK3args am_nfs3_link_3_arg; 321 am_READDIR3args am_nfs3_readdir_3_arg; 322 am_READDIRPLUS3args am_nfs3_readdirplus_3_arg; 323 am_FSSTAT3args am_nfs3_fsstat_3_arg; 324 am_FSINFO3args am_nfs3_fsinfo_3_arg; 325 am_PATHCONF3args am_nfs3_pathconf_3_arg; 326 am_COMMIT3args am_nfs3_commit_3_arg; 327 } argument; 328 char *result; 329 xdrproc_t _xdr_argument, _xdr_result; 330 nfssvcproc_t local; 331 332 switch (rqstp->rq_proc) { 333 case AM_NFS3_NULL: 334 _xdr_argument = (xdrproc_t) xdr_void; 335 _xdr_result = (xdrproc_t) xdr_void; 336 local = (nfssvcproc_t) am_nfs3_null_3_svc; 337 break; 338 339 case AM_NFS3_GETATTR: 340 _xdr_argument = (xdrproc_t) xdr_am_GETATTR3args; 341 _xdr_result = (xdrproc_t) xdr_am_GETATTR3res; 342 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_getattr_3_svc; 343 break; 344 345 case AM_NFS3_SETATTR: 346 _xdr_argument = (xdrproc_t) xdr_am_SETATTR3args; 347 _xdr_result = (xdrproc_t) xdr_am_SETATTR3res; 348 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_setattr_3_svc; 349 break; 350 351 case AM_NFS3_LOOKUP: 352 _xdr_argument = (xdrproc_t) xdr_am_LOOKUP3args; 353 _xdr_result = (xdrproc_t) xdr_am_LOOKUP3res; 354 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_lookup_3_svc; 355 break; 356 357 case AM_NFS3_ACCESS: 358 _xdr_argument = (xdrproc_t) xdr_am_ACCESS3args; 359 _xdr_result = (xdrproc_t) xdr_am_ACCESS3res; 360 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_access_3_svc; 361 break; 362 363 case AM_NFS3_READLINK: 364 _xdr_argument = (xdrproc_t) xdr_am_READLINK3args; 365 _xdr_result = (xdrproc_t) xdr_am_READLINK3res; 366 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readlink_3_svc; 367 break; 368 369 case AM_NFS3_READ: 370 _xdr_argument = (xdrproc_t) xdr_am_READ3args; 371 _xdr_result = (xdrproc_t) xdr_am_READ3res; 372 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_read_3_svc; 373 break; 374 375 case AM_NFS3_WRITE: 376 _xdr_argument = (xdrproc_t) xdr_am_WRITE3args; 377 _xdr_result = (xdrproc_t) xdr_am_WRITE3res; 378 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_write_3_svc; 379 break; 380 381 case AM_NFS3_CREATE: 382 _xdr_argument = (xdrproc_t) xdr_am_CREATE3args; 383 _xdr_result = (xdrproc_t) xdr_am_CREATE3res; 384 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_create_3_svc; 385 break; 386 387 case AM_NFS3_MKDIR: 388 _xdr_argument = (xdrproc_t) xdr_am_MKDIR3args; 389 _xdr_result = (xdrproc_t) xdr_am_MKDIR3res; 390 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_mkdir_3_svc; 391 break; 392 393 case AM_NFS3_SYMLINK: 394 _xdr_argument = (xdrproc_t) xdr_am_SYMLINK3args; 395 _xdr_result = (xdrproc_t) xdr_am_SYMLINK3res; 396 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_symlink_3_svc; 397 break; 398 399 case AM_NFS3_MKNOD: 400 _xdr_argument = (xdrproc_t) xdr_am_MKNOD3args; 401 _xdr_result = (xdrproc_t) xdr_am_MKNOD3res; 402 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_mknod_3_svc; 403 break; 404 405 case AM_NFS3_REMOVE: 406 _xdr_argument = (xdrproc_t) xdr_am_REMOVE3args; 407 _xdr_result = (xdrproc_t) xdr_am_REMOVE3res; 408 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_remove_3_svc; 409 break; 410 411 case AM_NFS3_RMDIR: 412 _xdr_argument = (xdrproc_t) xdr_am_RMDIR3args; 413 _xdr_result = (xdrproc_t) xdr_am_RMDIR3res; 414 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_rmdir_3_svc; 415 break; 416 417 case AM_NFS3_RENAME: 418 _xdr_argument = (xdrproc_t) xdr_am_RENAME3args; 419 _xdr_result = (xdrproc_t) xdr_am_RENAME3res; 420 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_rename_3_svc; 421 break; 422 423 case AM_NFS3_LINK: 424 _xdr_argument = (xdrproc_t) xdr_am_LINK3args; 425 _xdr_result = (xdrproc_t) xdr_am_LINK3res; 426 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_link_3_svc; 427 break; 428 429 case AM_NFS3_READDIR: 430 _xdr_argument = (xdrproc_t) xdr_am_READDIR3args; 431 _xdr_result = (xdrproc_t) xdr_am_READDIR3res; 432 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readdir_3_svc; 433 break; 434 435 case AM_NFS3_READDIRPLUS: 436 _xdr_argument = (xdrproc_t) xdr_am_READDIRPLUS3args; 437 _xdr_result = (xdrproc_t) xdr_am_READDIRPLUS3res; 438 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readdirplus_3_svc; 439 break; 440 441 case AM_NFS3_FSSTAT: 442 _xdr_argument = (xdrproc_t) xdr_am_FSSTAT3args; 443 _xdr_result = (xdrproc_t) xdr_am_FSSTAT3res; 444 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_fsstat_3_svc; 445 break; 446 447 case AM_NFS3_FSINFO: 448 _xdr_argument = (xdrproc_t) xdr_am_FSINFO3args; 449 _xdr_result = (xdrproc_t) xdr_am_FSINFO3res; 450 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_fsinfo_3_svc; 451 break; 452 453 case AM_NFS3_PATHCONF: 454 _xdr_argument = (xdrproc_t) xdr_am_PATHCONF3args; 455 _xdr_result = (xdrproc_t) xdr_am_PATHCONF3res; 456 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_pathconf_3_svc; 457 break; 458 459 case AM_NFS3_COMMIT: 460 _xdr_argument = (xdrproc_t) xdr_am_COMMIT3args; 461 _xdr_result = (xdrproc_t) xdr_am_COMMIT3res; 462 local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_commit_3_svc; 463 break; 464 465 default: 466 svcerr_noproc (transp); 467 return; 468 } 469 470 memset ((char *)&argument, 0, sizeof (argument)); 471 472 if (!svc_getargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { 473 plog(XLOG_ERROR, 474 "NFS xdr decode failed for %d %d %d", 475 (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc); 476 svcerr_decode(transp); 477 return; 478 } 479 480 result = (*local) (&argument, rqstp); 481 if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) { 482 svcerr_systemerr (transp); 483 } 484 485 if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { 486 plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_3"); 487 going_down(1); 488 } 489 return; 490 } 491