nfs_server.c revision 18c2aff776a775d34a4c9893a4c72e0434d68e36
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1997 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Portions of this source code were derived from Berkeley 4.3 BSD
* under license from the Regents of the University of California.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* the code in this file was copied from Brad ... ??
*/
#include <stdio.h>
#include <stdlib.h>
#include <libintl.h>
#include <rpc/rpc.h>
#include <rpcsvc/nfs_prot.h>
#include "vold.h"
int trace = 0; /* for tracing our NFS code */
extern int __rpc_get_local_uid(SVCXPRT *trans, uid_t *uid_out);
void
nfs_program_2(rqstp, transp)
struct svc_req *rqstp;
SVCXPRT *transp;
{
extern void trace_call(u_long, char *);
extern void trace_return(u_long, char *);
union {
nfs_fh nfsproc_getattr_2_svc_arg;
sattrargs nfsproc_setattr_2_svc_arg;
diropargs nfsproc_lookup_2_svc_arg;
nfs_fh nfsproc_readlink_2_svc_arg;
#ifndef RPCGEN_CODE_IS_BETTER
/* in brad's original code */
readres nfsproc_read_2_svc_arg;
#else
/* generated by rpcgen */
readargs nfsproc_read_2_svc_arg;
#endif
writeargs nfsproc_write_2_svc_arg;
createargs nfsproc_create_2_svc_arg;
diropargs nfsproc_remove_2_svc_arg;
renameargs nfsproc_rename_2_svc_arg;
linkargs nfsproc_link_2_svc_arg;
symlinkargs nfsproc_symlink_2_svc_arg;
createargs nfsproc_mkdir_2_svc_arg;
diropargs nfsproc_rmdir_2_svc_arg;
readdirargs nfsproc_readdir_2_svc_arg;
nfs_fh nfsproc_statfs_2_svc_arg;
} argument;
char *result;
bool_t (*xdr_argument)();
bool_t (*xdr_result)();
char *(*local)();
uid_t uid;
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply(transp, xdr_void, (caddr_t)NULL);
return;
case NFSPROC_GETATTR:
xdr_argument = xdr_nfs_fh;
xdr_result = xdr_attrstat;
local = (char *(*)()) nfsproc_getattr_2_svc;
break;
case NFSPROC_SETATTR:
xdr_argument = xdr_sattrargs;
xdr_result = xdr_attrstat;
local = (char *(*)()) nfsproc_setattr_2_svc;
break;
case NFSPROC_ROOT:
xdr_argument = xdr_void;
xdr_result = xdr_void;
local = (char *(*)()) nfsproc_root_2_svc;
break;
case NFSPROC_LOOKUP:
xdr_argument = xdr_diropargs;
xdr_result = xdr_diropres;
local = (char *(*)()) nfsproc_lookup_2_svc;
break;
case NFSPROC_READLINK:
xdr_argument = xdr_nfs_fh;
xdr_result = xdr_readlinkres;
local = (char *(*)()) nfsproc_readlink_2_svc;
break;
case NFSPROC_READ:
xdr_argument = xdr_readargs;
xdr_result = xdr_readres;
local = (char *(*)()) nfsproc_read_2_svc;
break;
case NFSPROC_WRITECACHE:
xdr_argument = xdr_void;
xdr_result = xdr_void;
local = (char *(*)()) nfsproc_writecache_2_svc;
break;
case NFSPROC_WRITE:
xdr_argument = xdr_writeargs;
xdr_result = xdr_attrstat;
local = (char *(*)()) nfsproc_write_2_svc;
break;
case NFSPROC_CREATE:
xdr_argument = xdr_createargs;
xdr_result = xdr_diropres;
local = (char *(*)()) nfsproc_create_2_svc;
break;
case NFSPROC_REMOVE:
xdr_argument = xdr_diropargs;
xdr_result = xdr_nfsstat;
local = (char *(*)()) nfsproc_remove_2_svc;
break;
case NFSPROC_RENAME:
xdr_argument = xdr_renameargs;
xdr_result = xdr_nfsstat;
local = (char *(*)()) nfsproc_rename_2_svc;
break;
case NFSPROC_LINK:
xdr_argument = xdr_linkargs;
xdr_result = xdr_nfsstat;
local = (char *(*)()) nfsproc_link_2_svc;
break;
case NFSPROC_SYMLINK:
xdr_argument = xdr_symlinkargs;
xdr_result = xdr_nfsstat;
local = (char *(*)()) nfsproc_symlink_2_svc;
break;
case NFSPROC_MKDIR:
xdr_argument = xdr_createargs;
xdr_result = xdr_diropres;
local = (char *(*)()) nfsproc_mkdir_2_svc;
break;
case NFSPROC_RMDIR:
xdr_argument = xdr_diropargs;
xdr_result = xdr_nfsstat;
local = (char *(*)()) nfsproc_rmdir_2_svc;
break;
case NFSPROC_READDIR:
xdr_argument = xdr_readdirargs;
xdr_result = xdr_readdirres;
local = (char *(*)()) nfsproc_readdir_2_svc;
break;
case NFSPROC_STATFS:
xdr_argument = xdr_nfs_fh;
xdr_result = xdr_statfsres;
local = (char *(*)()) nfsproc_statfs_2_svc;
break;
default:
svcerr_noproc(transp);
return;
}
/*
* verify that AUTH_LOOPBACK credentials that follow are valid.
* if the uid is not root, the credentials cannot be trusted,
* so reject the request
*/
if ((__rpc_get_local_uid(transp, &uid) < 0) || (uid != 0)) {
svcerr_auth(transp, AUTH_BADCRED);
return;
}
if (rqstp->rq_cred.oa_flavor != AUTH_LOOPBACK) {
fatal(gettext("file system mounted improperly, only the \
AUTH_LOOPBACK credential is supported\n"));
/*NOTREACHED*/
}
(void) memset(&argument, 0, sizeof (argument));
if (! svc_getargs(transp, xdr_argument, (caddr_t)&argument)) {
svcerr_decode(transp);
return;
}
if (trace) {
trace_call(rqstp->rq_proc, (char *)&argument);
}
result = (*local)(&argument, rqstp);
if (trace) {
trace_return(rqstp->rq_proc, result);
}
if (!svc_sendreply(transp, xdr_result, (caddr_t)result)) {
svcerr_systemerr(transp);
}
if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) {
exit(1);
}
}