1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-02 08:42:48 +00:00

Seperate the export check in VFS_FHTOVP, exports are now checked via

VFS_CHECKEXP.

Add fh(open|stat|stafs) syscalls to allow userland to query filesystems
based on (network) filehandle.

Obtained from:	NetBSD
This commit is contained in:
Alfred Perlstein 1999-09-11 00:46:08 +00:00
parent e14f7e789a
commit c24fda81c9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=51138
49 changed files with 910 additions and 274 deletions

View File

@ -530,6 +530,7 @@ struct vfsops coda_vfsops = {
coda_sync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
vfs_stdinit
};

View File

@ -68,8 +68,9 @@ static int cd9660_unmount __P((struct mount *, int, struct proc *));
static int cd9660_root __P((struct mount *, struct vnode **));
static int cd9660_statfs __P((struct mount *, struct statfs *, struct proc *));
static int cd9660_vget __P((struct mount *, ino_t, struct vnode **));
static int cd9660_fhtovp __P((struct mount *, struct fid *, struct sockaddr *,
struct vnode **, int *, struct ucred **));
static int cd9660_fhtovp __P((struct mount *, struct fid *, struct vnode **));
static int cd9660_checkexp __P((struct mount *, struct sockaddr *,
int *, struct ucred **));
static int cd9660_vptofh __P((struct vnode *, struct fid *));
static struct vfsops cd9660_vfsops = {
@ -82,6 +83,7 @@ static struct vfsops cd9660_vfsops = {
vfs_stdsync,
cd9660_vget,
cd9660_fhtovp,
cd9660_checkexp,
cd9660_vptofh,
cd9660_init,
};
@ -620,18 +622,13 @@ struct ifid {
/* ARGSUSED */
int
cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
cd9660_fhtovp(mp, fhp, vpp)
register struct mount *mp;
struct fid *fhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
struct ifid *ifhp = (struct ifid *)fhp;
register struct iso_node *ip;
register struct netcred *np;
register struct iso_mnt *imp = VFSTOISOFS(mp);
struct vnode *nvp;
int error;
@ -640,13 +637,6 @@ cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
ifhp->ifid_ino, ifhp->ifid_start);
#endif
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &imp->im_export, nam);
if (np == NULL)
return (EACCES);
if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
@ -658,6 +648,28 @@ cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
return (ESTALE);
}
*vpp = nvp;
return (0);
}
int
cd9660_checkexp(mp, nam, exflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred **credanonp;
{
register struct netcred *np;
register struct iso_mnt *imp;
imp = VFSTOISOFS(mp);
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &imp->im_export, nam);
if (np == NULL)
return (EACCES);
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return (0);

View File

@ -530,6 +530,7 @@ struct vfsops coda_vfsops = {
coda_sync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
vfs_stdinit
};

View File

@ -224,6 +224,7 @@ static struct vfsops fdesc_vfsops = {
vfs_stdsync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
fdesc_init,
};

View File

@ -75,8 +75,9 @@ static int update_mp __P((struct mount *mp, struct msdosfs_args *argp));
static int mountmsdosfs __P((struct vnode *devvp, struct mount *mp,
struct proc *p, struct msdosfs_args *argp));
static int msdosfs_fhtovp __P((struct mount *, struct fid *,
struct sockaddr *, struct vnode **, int *,
struct ucred **));
struct vnode **));
static int msdosfs_checkexp __P((struct mount *, struct sockaddr *,
int *, struct ucred **));
static int msdosfs_mount __P((struct mount *, char *, caddr_t,
struct nameidata *, struct proc *));
static int msdosfs_root __P((struct mount *, struct vnode **));
@ -915,29 +916,38 @@ msdosfs_sync(mp, waitfor, cred, p)
}
static int
msdosfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
msdosfs_fhtovp(mp, fhp, vpp)
struct mount *mp;
struct fid *fhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
struct defid *defhp = (struct defid *) fhp;
struct denode *dep;
struct netcred *np;
int error;
np = vfs_export_lookup(mp, &pmp->pm_export, nam);
if (np == NULL)
return (EACCES);
error = deget(pmp, defhp->defid_dirclust, defhp->defid_dirofs, &dep);
if (error) {
*vpp = NULLVP;
return (error);
}
*vpp = DETOV(dep);
return (0);
}
static int
msdosfs_checkexp(mp, nam, exflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred **credanonp;
{
struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
struct netcred *np;
np = vfs_export_lookup(mp, &pmp->pm_export, nam);
if (np == NULL)
return (EACCES);
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return (0);
@ -970,6 +980,7 @@ static struct vfsops msdosfs_vfsops = {
msdosfs_sync,
vfs_stdvget,
msdosfs_fhtovp,
msdosfs_checkexp,
msdosfs_vptofh,
msdosfs_init
};

View File

@ -93,9 +93,10 @@ static int ntfs_vptofh __P((struct vnode *, struct fid *));
static int ntfs_init __P((struct vfsconf *));
#if 0 /* may be implemented at a later date */
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct sockaddr *, struct vnode **,
int *, struct ucred **));
#endif
struct vnode **));
static int ntfs_checkexp __P((struct vnode *, struct mbuf *,
int *, struct ucred **));
#endif /* 0, default ops in FreeBSD */
#elif defined(__NetBSD__)
static void ntfs_init __P((void));
static int ntfs_fhtovp __P((struct mount *, struct fid *,
@ -952,6 +953,7 @@ static struct vfsops ntfs_vfsops = {
vfs_stdsync,
ntfs_vget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
ntfs_init,
NULL

View File

@ -57,8 +57,9 @@
static MALLOC_DEFINE(M_NULLFSMNT, "NULLFS mount", "NULLFS mount structure");
static int nullfs_fhtovp __P((struct mount *mp, struct fid *fidp,
struct sockaddr *nam, struct vnode **vpp,
int *exflagsp, struct ucred **credanonp));
struct vnode **vpp));
static int nullfs_checkexp __P((struct mount *mp, struct sockaddr *nam,
int *extflagsp, struct ucred **credanonp));
static int nullfs_mount __P((struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p));
static int nullfs_quotactl __P((struct mount *mp, int cmd, uid_t uid,
@ -385,17 +386,25 @@ nullfs_vget(mp, ino, vpp)
}
static int
nullfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
nullfs_fhtovp(mp, fidp, vpp)
struct mount *mp;
struct fid *fidp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred**credanonp;
{
return VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, nam,
vpp, exflagsp, credanonp);
return VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, vpp);
}
static int
nullfs_checkexp(mp, nam, extflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *extflagsp;
struct ucred **credanonp;
{
return VFS_CHECKEXP(MOUNTTONULLMOUNT(mp)->nullm_vfs, nam,
extflagsp, credanonp);
}
static int
@ -416,6 +425,7 @@ static struct vfsops null_vfsops = {
nullfs_sync,
nullfs_vget,
nullfs_fhtovp,
nullfs_checkexp,
nullfs_vptofh,
nullfs_init,
};

View File

@ -253,6 +253,7 @@ static struct vfsops portal_vfsops = {
vfs_stdsync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
vfs_stdinit,
};

View File

@ -170,6 +170,7 @@ static struct vfsops procfs_vfsops = {
vfs_stdsync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
vfs_stdinit,
};

View File

@ -56,8 +56,9 @@
static MALLOC_DEFINE(M_UMAPFSMNT, "UMAP mount", "UMAP mount structure");
static int umapfs_fhtovp __P((struct mount *mp, struct fid *fidp,
struct sockaddr *nam, struct vnode **vpp,
int *exflagsp, struct ucred **credanonp));
struct vnode **vpp));
static int umapfs_checkexp __P((struct mount *mp, struct sockaddr *nam,
int *extflagsp, struct ucred **credanonp));
static int umapfs_mount __P((struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p));
static int umapfs_quotactl __P((struct mount *mp, int cmd, uid_t uid,
@ -398,16 +399,25 @@ umapfs_vget(mp, ino, vpp)
}
static int
umapfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
umapfs_fhtovp(mp, fidp, vpp)
struct mount *mp;
struct fid *fidp;
struct sockaddr *nam;
struct vnode **vpp;
{
return (VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, fidp, vpp));
}
static int
umapfs_checkexp(mp, nam, exflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred**credanonp;
struct ucred **credanonp;
{
return (VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, fidp, nam, vpp, exflagsp,credanonp));
return (VFS_CHECKEXP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, nam,
exflagsp, credanonp));
}
static int
@ -428,6 +438,7 @@ static struct vfsops umap_vfsops = {
umapfs_sync,
umapfs_vget,
umapfs_fhtovp,
umapfs_checkexp,
umapfs_vptofh,
umapfs_init,
};

View File

@ -496,7 +496,7 @@ union_statfs(mp, sbp, p)
static struct vfsops union_vfsops = {
union_mount,
vfs_stdstart,
vfs_stdstart, /* underlying start already done */
union_unmount,
union_root,
vfs_stdquotactl,
@ -504,6 +504,7 @@ static struct vfsops union_vfsops = {
vfs_stdsync, /* XXX assumes no cached data on union level */
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
union_init,
};

View File

@ -37,6 +37,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94
* $FreeBSD$
*/
#include "opt_quota.h"
@ -65,8 +66,7 @@
#include <gnu/ext2fs/ext2_fs.h>
#include <gnu/ext2fs/ext2_fs_sb.h>
static int ext2_fhtovp __P((struct mount *, struct fid *, struct sockaddr *,
struct vnode **, int *, struct ucred **));
static int ext2_fhtovp __P((struct mount *, struct fid *, struct vnode **));
static int ext2_flushfiles __P((struct mount *mp, int flags, struct proc *p));
static int ext2_mount __P((struct mount *,
char *, caddr_t, struct nameidata *, struct proc *));
@ -92,6 +92,7 @@ static struct vfsops ext2fs_vfsops = {
ext2_sync,
ext2_vget,
ext2_fhtovp,
ufs_check_export,
ext2_vptofh,
ext2_init,
};
@ -1113,13 +1114,10 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
* those rights via. exflagsp and credanonp
*/
static int
ext2_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
ext2_fhtovp(mp, fhp, vpp)
register struct mount *mp;
struct fid *fhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
register struct ufid *ufhp;
struct ext2_sb_info *fs;
@ -1129,7 +1127,7 @@ ext2_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
if (ufhp->ufid_ino < ROOTINO ||
ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group)
return (ESTALE);
return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp));
return (ufs_fhtovp(mp, ufhp, vpp));
}
/*

View File

@ -37,6 +37,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94
* $FreeBSD$
*/
#include "opt_quota.h"
@ -65,8 +66,7 @@
#include <gnu/ext2fs/ext2_fs.h>
#include <gnu/ext2fs/ext2_fs_sb.h>
static int ext2_fhtovp __P((struct mount *, struct fid *, struct sockaddr *,
struct vnode **, int *, struct ucred **));
static int ext2_fhtovp __P((struct mount *, struct fid *, struct vnode **));
static int ext2_flushfiles __P((struct mount *mp, int flags, struct proc *p));
static int ext2_mount __P((struct mount *,
char *, caddr_t, struct nameidata *, struct proc *));
@ -92,6 +92,7 @@ static struct vfsops ext2fs_vfsops = {
ext2_sync,
ext2_vget,
ext2_fhtovp,
ufs_check_export,
ext2_vptofh,
ext2_init,
};
@ -1113,13 +1114,10 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
* those rights via. exflagsp and credanonp
*/
static int
ext2_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
ext2_fhtovp(mp, fhp, vpp)
register struct mount *mp;
struct fid *fhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
register struct ufid *ufhp;
struct ext2_sb_info *fs;
@ -1129,7 +1127,7 @@ ext2_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
if (ufhp->ufid_ino < ROOTINO ||
ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group)
return (ESTALE);
return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp));
return (ufs_fhtovp(mp, ufhp, vpp));
}
/*

View File

@ -68,8 +68,9 @@ static int cd9660_unmount __P((struct mount *, int, struct proc *));
static int cd9660_root __P((struct mount *, struct vnode **));
static int cd9660_statfs __P((struct mount *, struct statfs *, struct proc *));
static int cd9660_vget __P((struct mount *, ino_t, struct vnode **));
static int cd9660_fhtovp __P((struct mount *, struct fid *, struct sockaddr *,
struct vnode **, int *, struct ucred **));
static int cd9660_fhtovp __P((struct mount *, struct fid *, struct vnode **));
static int cd9660_checkexp __P((struct mount *, struct sockaddr *,
int *, struct ucred **));
static int cd9660_vptofh __P((struct vnode *, struct fid *));
static struct vfsops cd9660_vfsops = {
@ -82,6 +83,7 @@ static struct vfsops cd9660_vfsops = {
vfs_stdsync,
cd9660_vget,
cd9660_fhtovp,
cd9660_checkexp,
cd9660_vptofh,
cd9660_init,
};
@ -620,18 +622,13 @@ struct ifid {
/* ARGSUSED */
int
cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
cd9660_fhtovp(mp, fhp, vpp)
register struct mount *mp;
struct fid *fhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
struct ifid *ifhp = (struct ifid *)fhp;
register struct iso_node *ip;
register struct netcred *np;
register struct iso_mnt *imp = VFSTOISOFS(mp);
struct vnode *nvp;
int error;
@ -640,13 +637,6 @@ cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
ifhp->ifid_ino, ifhp->ifid_start);
#endif
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &imp->im_export, nam);
if (np == NULL)
return (EACCES);
if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
*vpp = NULLVP;
return (error);
@ -658,6 +648,28 @@ cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
return (ESTALE);
}
*vpp = nvp;
return (0);
}
int
cd9660_checkexp(mp, nam, exflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred **credanonp;
{
register struct netcred *np;
register struct iso_mnt *imp;
imp = VFSTOISOFS(mp);
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &imp->im_export, nam);
if (np == NULL)
return (EACCES);
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return (0);

View File

@ -2,6 +2,7 @@
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.63 1999/08/28 00:46:19 peter Exp
*/
@ -316,9 +317,9 @@ struct sysent sysent[] = {
{ 0, (sy_call_t *)nosys }, /* 294 = nosys */
{ 0, (sy_call_t *)nosys }, /* 295 = nosys */
{ 0, (sy_call_t *)nosys }, /* 296 = nosys */
{ 0, (sy_call_t *)nosys }, /* 297 = nosys */
{ 0, (sy_call_t *)nosys }, /* 298 = nosys */
{ 0, (sy_call_t *)nosys }, /* 299 = nosys */
{ 2, (sy_call_t *)fhstatfs }, /* 297 = fhstatfs */
{ 2, (sy_call_t *)fhopen }, /* 298 = fhopen */
{ 2, (sy_call_t *)fhstat }, /* 299 = fhstat */
{ 1, (sy_call_t *)modnext }, /* 300 = modnext */
{ 2, (sy_call_t *)modstat }, /* 301 = modstat */
{ 1, (sy_call_t *)modfnext }, /* 302 = modfnext */

View File

@ -2,6 +2,7 @@
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.63 1999/08/28 00:46:19 peter Exp
*/
@ -303,9 +304,9 @@ char *syscallnames[] = {
"#294", /* 294 = nosys */
"#295", /* 295 = nosys */
"#296", /* 296 = nosys */
"#297", /* 297 = nosys */
"#298", /* 298 = nosys */
"#299", /* 299 = nosys */
"fhstatfs", /* 297 = fhstatfs */
"fhopen", /* 298 = fhopen */
"fhstat", /* 299 = fhstat */
"modnext", /* 300 = modnext */
"modstat", /* 301 = modstat */
"modfnext", /* 302 = modfnext */

View File

@ -428,9 +428,10 @@
294 UNIMPL NOHIDE nosys
295 UNIMPL NOHIDE nosys
296 UNIMPL NOHIDE nosys
297 UNIMPL NOHIDE nosys
298 UNIMPL NOHIDE nosys
299 UNIMPL NOHIDE nosys
; XXX 297 is 300 in NetBSD
297 STD BSD { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
298 STD BSD { int fhopen(const struct fhandle *u_fhp, int flags); }
299 STD BSD { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
; syscall numbers for FreeBSD
300 STD BSD { int modnext(int modid); }
301 STD BSD { int modstat(int modid, struct module_stat* stat); }

View File

@ -580,12 +580,19 @@ vfs_stdvget (mp, ino, vpp)
}
int
vfs_stdfhtovp (mp, fhp, nam, vpp, exflagsp, credanonp)
vfs_stdfhtovp (mp, fhp, vpp)
struct mount *mp;
struct fid *fhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
{
return (EOPNOTSUPP);
}
int
vfs_stdcheckexp (mp, nam, extflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *extflagsp;
struct ucred **credanonp;
{
return (EOPNOTSUPP);

View File

@ -46,6 +46,8 @@
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/sysent.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/sysproto.h>
#include <sys/namei.h>
#include <sys/filedesc.h>
@ -56,8 +58,6 @@
#include <sys/stat.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/dirent.h>
@ -3130,3 +3130,292 @@ __getcwd(p, uap)
free(buf, M_TEMP);
return (error);
}
/*
* Get (NFS) file handle
*/
#ifndef _SYS_SYSPROTO_H_
struct getfh_args {
char *fname;
fhandle_t *fhp;
};
#endif
int
getfh(p, uap)
struct proc *p;
register struct getfh_args *uap;
{
struct nameidata nd;
fhandle_t fh;
register struct vnode *vp;
int error;
/*
* Must be super user
*/
error = suser(p);
if (error)
return (error);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
error = namei(&nd);
if (error)
return (error);
vp = nd.ni_vp;
bzero(&fh, sizeof(fh));
fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
error = VFS_VPTOFH(vp, &fh.fh_fid);
vput(vp);
if (error)
return (error);
error = copyout(&fh, uap->fhp, sizeof (fh));
return (error);
}
/*
* syscall for the rpc.lockd to use to translate a NFS file handle into
* an open descriptor.
*
* warning: do not remove the suser() call or this becomes one giant
* security hole.
*/
#ifndef _SYS_SYSPROTO_H_
struct fhopen_args {
const struct fhandle *u_fhp;
int flags;
};
#endif
int
fhopen(p, uap)
struct proc *p;
struct fhopen_args /* {
syscallarg(const struct fhandle *) u_fhp;
syscallarg(int) flags;
} */ *uap;
{
struct mount *mp;
struct vnode *vp;
struct fhandle fhp;
struct vattr vat;
struct vattr *vap = &vat;
struct flock lf;
struct file *fp;
register struct filedesc *fdp = p->p_fd;
int fmode, mode, error, type;
struct file *nfp;
int indx;
/*
* Must be super user
*/
error = suser(p);
if (error)
return (error);
fmode = FFLAGS(SCARG(uap, flags));
/* why not allow a non-read/write open for our lockd? */
if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
return (EINVAL);
error = copyin(SCARG(uap,u_fhp), &fhp, sizeof(fhp));
if (error)
return(error);
/* find the mount point */
mp = vfs_getvfs(&fhp.fh_fsid);
if (mp == NULL)
return (ESTALE);
/* now give me my vnode, it gets returned to me locked */
error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
if (error)
return (error);
/*
* from now on we have to make sure not
* to forget about the vnode
* any error that causes an abort must vput(vp)
* just set error = err and 'goto bad;'.
*/
/*
* from vn_open
*/
if (vp->v_type == VLNK) {
error = EMLINK;
goto bad;
}
if (vp->v_type == VSOCK) {
error = EOPNOTSUPP;
goto bad;
}
mode = 0;
if (fmode & (FWRITE | O_TRUNC)) {
if (vp->v_type == VDIR) {
error = EISDIR;
goto bad;
}
error = vn_writechk(vp);
if (error)
goto bad;
mode |= VWRITE;
}
if (fmode & FREAD)
mode |= VREAD;
if (mode) {
error = VOP_ACCESS(vp, mode, p->p_ucred, p);
if (error)
goto bad;
}
if (fmode & O_TRUNC) {
VOP_UNLOCK(vp, 0, p); /* XXX */
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */
VATTR_NULL(vap);
vap->va_size = 0;
error = VOP_SETATTR(vp, vap, p->p_ucred, p);
if (error)
goto bad;
}
error = VOP_OPEN(vp, fmode, p->p_ucred, p);
if (error)
goto bad;
/*
* Make sure that a VM object is created for VMIO support.
*/
if (vn_canvmio(vp) == TRUE) {
if ((error = vfs_object_create(vp, p, p->p_ucred)) != 0)
goto bad;
}
if (fmode & FWRITE)
vp->v_writecount++;
/*
* end of vn_open code
*/
if ((error = falloc(p, &nfp, &indx)) != 0)
goto bad;
fp = nfp;
nfp->f_data = (caddr_t)vp;
nfp->f_flag = fmode & FMASK;
nfp->f_ops = &vnops;
nfp->f_type = DTYPE_VNODE;
if (fmode & (O_EXLOCK | O_SHLOCK)) {
lf.l_whence = SEEK_SET;
lf.l_start = 0;
lf.l_len = 0;
if (fmode & O_EXLOCK)
lf.l_type = F_WRLCK;
else
lf.l_type = F_RDLCK;
type = F_FLOCK;
if ((fmode & FNONBLOCK) == 0)
type |= F_WAIT;
VOP_UNLOCK(vp, 0, p);
if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) {
(void) vn_close(vp, fp->f_flag, fp->f_cred, p);
ffree(fp);
fdp->fd_ofiles[indx] = NULL;
return (error);
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
fp->f_flag |= FHASLOCK;
}
if ((vp->v_type == VREG) && (vp->v_object == NULL))
vfs_object_create(vp, p, p->p_ucred);
VOP_UNLOCK(vp, 0, p);
p->p_retval[0] = indx;
return (0);
bad:
vput(vp);
return (error);
}
#ifndef _SYS_SYSPROTO_H_
struct fhstat_args {
struct fhandle *u_fhp;
struct stat *sb;
};
#endif
int
fhstat(p, uap)
struct proc *p;
register struct fhstat_args /* {
syscallarg(struct fhandle *) u_fhp;
syscallarg(struct stat *) sb;
} */ *uap;
{
struct stat sb;
fhandle_t fh;
struct mount *mp;
struct vnode *vp;
int error;
/*
* Must be super user
*/
error = suser(p);
if (error)
return (error);
error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t));
if (error)
return (error);
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
return (ESTALE);
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
return (error);
error = vn_stat(vp, &sb, p);
vput(vp);
if (error)
return (error);
error = copyout(&sb, SCARG(uap, sb), sizeof(sb));
return (error);
}
#ifndef _SYS_SYSPROTO_H_
struct fhstatfs_args {
struct fhandle *u_fhp;
struct statfs *buf;
};
#endif
int
fhstatfs(p, uap)
struct proc *p;
struct fhstatfs_args /* {
syscallarg(struct fhandle) *u_fhp;
syscallarg(struct statfs) *buf;
} */ *uap;
{
struct statfs *sp;
struct mount *mp;
struct vnode *vp;
struct statfs sb;
fhandle_t fh;
int error;
/*
* Must be super user
*/
if ((error = suser(p)))
return (error);
if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0)
return (error);
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
return (ESTALE);
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
return (error);
mp = vp->v_mount;
sp = &mp->mnt_stat;
vput(vp);
if ((error = VFS_STATFS(mp, sp, p)) != 0)
return (error);
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
if (suser_xxx(p->p_ucred, 0, 0)) {
bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
sp = &sb;
}
return (copyout(sp, SCARG(uap, buf), sizeof(*sp)));
}

View File

@ -46,6 +46,8 @@
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/sysent.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/sysproto.h>
#include <sys/namei.h>
#include <sys/filedesc.h>
@ -56,8 +58,6 @@
#include <sys/stat.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/dirent.h>
@ -3130,3 +3130,292 @@ __getcwd(p, uap)
free(buf, M_TEMP);
return (error);
}
/*
* Get (NFS) file handle
*/
#ifndef _SYS_SYSPROTO_H_
struct getfh_args {
char *fname;
fhandle_t *fhp;
};
#endif
int
getfh(p, uap)
struct proc *p;
register struct getfh_args *uap;
{
struct nameidata nd;
fhandle_t fh;
register struct vnode *vp;
int error;
/*
* Must be super user
*/
error = suser(p);
if (error)
return (error);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
error = namei(&nd);
if (error)
return (error);
vp = nd.ni_vp;
bzero(&fh, sizeof(fh));
fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
error = VFS_VPTOFH(vp, &fh.fh_fid);
vput(vp);
if (error)
return (error);
error = copyout(&fh, uap->fhp, sizeof (fh));
return (error);
}
/*
* syscall for the rpc.lockd to use to translate a NFS file handle into
* an open descriptor.
*
* warning: do not remove the suser() call or this becomes one giant
* security hole.
*/
#ifndef _SYS_SYSPROTO_H_
struct fhopen_args {
const struct fhandle *u_fhp;
int flags;
};
#endif
int
fhopen(p, uap)
struct proc *p;
struct fhopen_args /* {
syscallarg(const struct fhandle *) u_fhp;
syscallarg(int) flags;
} */ *uap;
{
struct mount *mp;
struct vnode *vp;
struct fhandle fhp;
struct vattr vat;
struct vattr *vap = &vat;
struct flock lf;
struct file *fp;
register struct filedesc *fdp = p->p_fd;
int fmode, mode, error, type;
struct file *nfp;
int indx;
/*
* Must be super user
*/
error = suser(p);
if (error)
return (error);
fmode = FFLAGS(SCARG(uap, flags));
/* why not allow a non-read/write open for our lockd? */
if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
return (EINVAL);
error = copyin(SCARG(uap,u_fhp), &fhp, sizeof(fhp));
if (error)
return(error);
/* find the mount point */
mp = vfs_getvfs(&fhp.fh_fsid);
if (mp == NULL)
return (ESTALE);
/* now give me my vnode, it gets returned to me locked */
error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
if (error)
return (error);
/*
* from now on we have to make sure not
* to forget about the vnode
* any error that causes an abort must vput(vp)
* just set error = err and 'goto bad;'.
*/
/*
* from vn_open
*/
if (vp->v_type == VLNK) {
error = EMLINK;
goto bad;
}
if (vp->v_type == VSOCK) {
error = EOPNOTSUPP;
goto bad;
}
mode = 0;
if (fmode & (FWRITE | O_TRUNC)) {
if (vp->v_type == VDIR) {
error = EISDIR;
goto bad;
}
error = vn_writechk(vp);
if (error)
goto bad;
mode |= VWRITE;
}
if (fmode & FREAD)
mode |= VREAD;
if (mode) {
error = VOP_ACCESS(vp, mode, p->p_ucred, p);
if (error)
goto bad;
}
if (fmode & O_TRUNC) {
VOP_UNLOCK(vp, 0, p); /* XXX */
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */
VATTR_NULL(vap);
vap->va_size = 0;
error = VOP_SETATTR(vp, vap, p->p_ucred, p);
if (error)
goto bad;
}
error = VOP_OPEN(vp, fmode, p->p_ucred, p);
if (error)
goto bad;
/*
* Make sure that a VM object is created for VMIO support.
*/
if (vn_canvmio(vp) == TRUE) {
if ((error = vfs_object_create(vp, p, p->p_ucred)) != 0)
goto bad;
}
if (fmode & FWRITE)
vp->v_writecount++;
/*
* end of vn_open code
*/
if ((error = falloc(p, &nfp, &indx)) != 0)
goto bad;
fp = nfp;
nfp->f_data = (caddr_t)vp;
nfp->f_flag = fmode & FMASK;
nfp->f_ops = &vnops;
nfp->f_type = DTYPE_VNODE;
if (fmode & (O_EXLOCK | O_SHLOCK)) {
lf.l_whence = SEEK_SET;
lf.l_start = 0;
lf.l_len = 0;
if (fmode & O_EXLOCK)
lf.l_type = F_WRLCK;
else
lf.l_type = F_RDLCK;
type = F_FLOCK;
if ((fmode & FNONBLOCK) == 0)
type |= F_WAIT;
VOP_UNLOCK(vp, 0, p);
if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) {
(void) vn_close(vp, fp->f_flag, fp->f_cred, p);
ffree(fp);
fdp->fd_ofiles[indx] = NULL;
return (error);
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
fp->f_flag |= FHASLOCK;
}
if ((vp->v_type == VREG) && (vp->v_object == NULL))
vfs_object_create(vp, p, p->p_ucred);
VOP_UNLOCK(vp, 0, p);
p->p_retval[0] = indx;
return (0);
bad:
vput(vp);
return (error);
}
#ifndef _SYS_SYSPROTO_H_
struct fhstat_args {
struct fhandle *u_fhp;
struct stat *sb;
};
#endif
int
fhstat(p, uap)
struct proc *p;
register struct fhstat_args /* {
syscallarg(struct fhandle *) u_fhp;
syscallarg(struct stat *) sb;
} */ *uap;
{
struct stat sb;
fhandle_t fh;
struct mount *mp;
struct vnode *vp;
int error;
/*
* Must be super user
*/
error = suser(p);
if (error)
return (error);
error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t));
if (error)
return (error);
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
return (ESTALE);
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
return (error);
error = vn_stat(vp, &sb, p);
vput(vp);
if (error)
return (error);
error = copyout(&sb, SCARG(uap, sb), sizeof(sb));
return (error);
}
#ifndef _SYS_SYSPROTO_H_
struct fhstatfs_args {
struct fhandle *u_fhp;
struct statfs *buf;
};
#endif
int
fhstatfs(p, uap)
struct proc *p;
struct fhstatfs_args /* {
syscallarg(struct fhandle) *u_fhp;
syscallarg(struct statfs) *buf;
} */ *uap;
{
struct statfs *sp;
struct mount *mp;
struct vnode *vp;
struct statfs sb;
fhandle_t fh;
int error;
/*
* Must be super user
*/
if ((error = suser(p)))
return (error);
if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0)
return (error);
if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
return (ESTALE);
if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
return (error);
mp = vp->v_mount;
sp = &mp->mnt_stat;
vput(vp);
if ((error = VFS_STATFS(mp, sp, p)) != 0)
return (error);
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
if (suser_xxx(p->p_ucred, 0, 0)) {
bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
sp = &sb;
}
return (copyout(sp, SCARG(uap, buf), sizeof(*sp)));
}

View File

@ -303,6 +303,7 @@ static struct vfsops devfs_vfsops = {
devfs_sync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
devfs_init
};

View File

@ -224,6 +224,7 @@ static struct vfsops fdesc_vfsops = {
vfs_stdsync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
fdesc_init,
};

View File

@ -252,6 +252,7 @@ static struct vfsops kernfs_vfsops = {
vfs_stdsync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
vfs_stdinit,
};

View File

@ -57,8 +57,9 @@
static MALLOC_DEFINE(M_NULLFSMNT, "NULLFS mount", "NULLFS mount structure");
static int nullfs_fhtovp __P((struct mount *mp, struct fid *fidp,
struct sockaddr *nam, struct vnode **vpp,
int *exflagsp, struct ucred **credanonp));
struct vnode **vpp));
static int nullfs_checkexp __P((struct mount *mp, struct sockaddr *nam,
int *extflagsp, struct ucred **credanonp));
static int nullfs_mount __P((struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p));
static int nullfs_quotactl __P((struct mount *mp, int cmd, uid_t uid,
@ -385,17 +386,25 @@ nullfs_vget(mp, ino, vpp)
}
static int
nullfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
nullfs_fhtovp(mp, fidp, vpp)
struct mount *mp;
struct fid *fidp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred**credanonp;
{
return VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, nam,
vpp, exflagsp, credanonp);
return VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, vpp);
}
static int
nullfs_checkexp(mp, nam, extflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *extflagsp;
struct ucred **credanonp;
{
return VFS_CHECKEXP(MOUNTTONULLMOUNT(mp)->nullm_vfs, nam,
extflagsp, credanonp);
}
static int
@ -416,6 +425,7 @@ static struct vfsops null_vfsops = {
nullfs_sync,
nullfs_vget,
nullfs_fhtovp,
nullfs_checkexp,
nullfs_vptofh,
nullfs_init,
};

View File

@ -253,6 +253,7 @@ static struct vfsops portal_vfsops = {
vfs_stdsync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
vfs_stdinit,
};

View File

@ -170,6 +170,7 @@ static struct vfsops procfs_vfsops = {
vfs_stdsync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
vfs_stdinit,
};

View File

@ -56,8 +56,9 @@
static MALLOC_DEFINE(M_UMAPFSMNT, "UMAP mount", "UMAP mount structure");
static int umapfs_fhtovp __P((struct mount *mp, struct fid *fidp,
struct sockaddr *nam, struct vnode **vpp,
int *exflagsp, struct ucred **credanonp));
struct vnode **vpp));
static int umapfs_checkexp __P((struct mount *mp, struct sockaddr *nam,
int *extflagsp, struct ucred **credanonp));
static int umapfs_mount __P((struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p));
static int umapfs_quotactl __P((struct mount *mp, int cmd, uid_t uid,
@ -398,16 +399,25 @@ umapfs_vget(mp, ino, vpp)
}
static int
umapfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
umapfs_fhtovp(mp, fidp, vpp)
struct mount *mp;
struct fid *fidp;
struct sockaddr *nam;
struct vnode **vpp;
{
return (VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, fidp, vpp));
}
static int
umapfs_checkexp(mp, nam, exflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred**credanonp;
struct ucred **credanonp;
{
return (VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, fidp, nam, vpp, exflagsp,credanonp));
return (VFS_CHECKEXP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, nam,
exflagsp, credanonp));
}
static int
@ -428,6 +438,7 @@ static struct vfsops umap_vfsops = {
umapfs_sync,
umapfs_vget,
umapfs_fhtovp,
umapfs_checkexp,
umapfs_vptofh,
umapfs_init,
};

View File

@ -496,7 +496,7 @@ union_statfs(mp, sbp, p)
static struct vfsops union_vfsops = {
union_mount,
vfs_stdstart,
vfs_stdstart, /* underlying start already done */
union_unmount,
union_root,
vfs_stdquotactl,
@ -504,6 +504,7 @@ static struct vfsops union_vfsops = {
vfs_stdsync, /* XXX assumes no cached data on union level */
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
union_init,
};

View File

@ -75,8 +75,9 @@ static int update_mp __P((struct mount *mp, struct msdosfs_args *argp));
static int mountmsdosfs __P((struct vnode *devvp, struct mount *mp,
struct proc *p, struct msdosfs_args *argp));
static int msdosfs_fhtovp __P((struct mount *, struct fid *,
struct sockaddr *, struct vnode **, int *,
struct ucred **));
struct vnode **));
static int msdosfs_checkexp __P((struct mount *, struct sockaddr *,
int *, struct ucred **));
static int msdosfs_mount __P((struct mount *, char *, caddr_t,
struct nameidata *, struct proc *));
static int msdosfs_root __P((struct mount *, struct vnode **));
@ -915,29 +916,38 @@ msdosfs_sync(mp, waitfor, cred, p)
}
static int
msdosfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
msdosfs_fhtovp(mp, fhp, vpp)
struct mount *mp;
struct fid *fhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
struct defid *defhp = (struct defid *) fhp;
struct denode *dep;
struct netcred *np;
int error;
np = vfs_export_lookup(mp, &pmp->pm_export, nam);
if (np == NULL)
return (EACCES);
error = deget(pmp, defhp->defid_dirclust, defhp->defid_dirofs, &dep);
if (error) {
*vpp = NULLVP;
return (error);
}
*vpp = DETOV(dep);
return (0);
}
static int
msdosfs_checkexp(mp, nam, exflagsp, credanonp)
struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred **credanonp;
{
struct msdosfsmount *pmp = VFSTOMSDOSFS(mp);
struct netcred *np;
np = vfs_export_lookup(mp, &pmp->pm_export, nam);
if (np == NULL)
return (EACCES);
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return (0);
@ -970,6 +980,7 @@ static struct vfsops msdosfs_vfsops = {
msdosfs_sync,
vfs_stdvget,
msdosfs_fhtovp,
msdosfs_checkexp,
msdosfs_vptofh,
msdosfs_init
};

View File

@ -1960,7 +1960,10 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag)
mp = vfs_getvfs(&fhp->fh_fsid);
if (!mp)
return (ESTALE);
error = VFS_FHTOVP(mp, &fhp->fh_fid, nam, vpp, &exflags, &credanon);
error = VFS_CHECKEXP(mp, nam, &exflags, &credanon);
if (error)
return (error);
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
if (error)
return (error);
#ifdef MNT_EXNORESPORT

View File

@ -1960,7 +1960,10 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag)
mp = vfs_getvfs(&fhp->fh_fsid);
if (!mp)
return (ESTALE);
error = VFS_FHTOVP(mp, &fhp->fh_fid, nam, vpp, &exflags, &credanon);
error = VFS_CHECKEXP(mp, nam, &exflags, &credanon);
if (error)
return (error);
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
if (error)
return (error);
#ifdef MNT_EXNORESPORT

View File

@ -120,49 +120,8 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, &nfsrvw_procrastinate
/*
* NFS server system calls
* getfh() lives here too, but maybe should move to kern/vfs_syscalls.c
*/
/*
* Get file handle system call
*/
#ifndef _SYS_SYSPROTO_H_
struct getfh_args {
char *fname;
fhandle_t *fhp;
};
#endif
int
getfh(p, uap)
struct proc *p;
register struct getfh_args *uap;
{
register struct vnode *vp;
fhandle_t fh;
int error;
struct nameidata nd;
/*
* Must be super user
*/
error = suser(p);
if(error)
return (error);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
error = namei(&nd);
if (error)
return (error);
vp = nd.ni_vp;
bzero((caddr_t)&fh, sizeof(fh));
fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
error = VFS_VPTOFH(vp, &fh.fh_fid);
vput(vp);
if (error)
return (error);
error = copyout((caddr_t)&fh, (caddr_t)uap->fhp, sizeof (fh));
return (error);
}
#endif /* NFS_NOSERVER */
/*
* Nfs server psuedo system call for the nfsd's

View File

@ -120,6 +120,7 @@ static struct vfsops nfs_vfsops = {
nfs_sync,
vfs_stdvget,
vfs_stdfhtovp, /* shouldn't happen */
vfs_stdcheckexp,
vfs_stdvptofh, /* shouldn't happen */
nfs_init,
nfs_uninit,

View File

@ -120,49 +120,8 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, &nfsrvw_procrastinate
/*
* NFS server system calls
* getfh() lives here too, but maybe should move to kern/vfs_syscalls.c
*/
/*
* Get file handle system call
*/
#ifndef _SYS_SYSPROTO_H_
struct getfh_args {
char *fname;
fhandle_t *fhp;
};
#endif
int
getfh(p, uap)
struct proc *p;
register struct getfh_args *uap;
{
register struct vnode *vp;
fhandle_t fh;
int error;
struct nameidata nd;
/*
* Must be super user
*/
error = suser(p);
if(error)
return (error);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
error = namei(&nd);
if (error)
return (error);
vp = nd.ni_vp;
bzero((caddr_t)&fh, sizeof(fh));
fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
error = VFS_VPTOFH(vp, &fh.fh_fid);
vput(vp);
if (error)
return (error);
error = copyout((caddr_t)&fh, (caddr_t)uap->fhp, sizeof (fh));
return (error);
}
#endif /* NFS_NOSERVER */
/*
* Nfs server psuedo system call for the nfsd's

View File

@ -1960,7 +1960,10 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag)
mp = vfs_getvfs(&fhp->fh_fsid);
if (!mp)
return (ESTALE);
error = VFS_FHTOVP(mp, &fhp->fh_fid, nam, vpp, &exflags, &credanon);
error = VFS_CHECKEXP(mp, nam, &exflags, &credanon);
if (error)
return (error);
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
if (error)
return (error);
#ifdef MNT_EXNORESPORT

View File

@ -120,6 +120,7 @@ static struct vfsops nfs_vfsops = {
nfs_sync,
vfs_stdvget,
vfs_stdfhtovp, /* shouldn't happen */
vfs_stdcheckexp,
vfs_stdvptofh, /* shouldn't happen */
nfs_init,
nfs_uninit,

View File

@ -1960,7 +1960,10 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag)
mp = vfs_getvfs(&fhp->fh_fsid);
if (!mp)
return (ESTALE);
error = VFS_FHTOVP(mp, &fhp->fh_fid, nam, vpp, &exflags, &credanon);
error = VFS_CHECKEXP(mp, nam, &exflags, &credanon);
if (error)
return (error);
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
if (error)
return (error);
#ifdef MNT_EXNORESPORT

View File

@ -120,49 +120,8 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, &nfsrvw_procrastinate
/*
* NFS server system calls
* getfh() lives here too, but maybe should move to kern/vfs_syscalls.c
*/
/*
* Get file handle system call
*/
#ifndef _SYS_SYSPROTO_H_
struct getfh_args {
char *fname;
fhandle_t *fhp;
};
#endif
int
getfh(p, uap)
struct proc *p;
register struct getfh_args *uap;
{
register struct vnode *vp;
fhandle_t fh;
int error;
struct nameidata nd;
/*
* Must be super user
*/
error = suser(p);
if(error)
return (error);
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
error = namei(&nd);
if (error)
return (error);
vp = nd.ni_vp;
bzero((caddr_t)&fh, sizeof(fh));
fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
error = VFS_VPTOFH(vp, &fh.fh_fid);
vput(vp);
if (error)
return (error);
error = copyout((caddr_t)&fh, (caddr_t)uap->fhp, sizeof (fh));
return (error);
}
#endif /* NFS_NOSERVER */
/*
* Nfs server psuedo system call for the nfsd's

View File

@ -93,9 +93,10 @@ static int ntfs_vptofh __P((struct vnode *, struct fid *));
static int ntfs_init __P((struct vfsconf *));
#if 0 /* may be implemented at a later date */
static int ntfs_fhtovp __P((struct mount *, struct fid *,
struct sockaddr *, struct vnode **,
int *, struct ucred **));
#endif
struct vnode **));
static int ntfs_checkexp __P((struct vnode *, struct mbuf *,
int *, struct ucred **));
#endif /* 0, default ops in FreeBSD */
#elif defined(__NetBSD__)
static void ntfs_init __P((void));
static int ntfs_fhtovp __P((struct mount *, struct fid *,
@ -952,6 +953,7 @@ static struct vfsops ntfs_vfsops = {
vfs_stdsync,
ntfs_vget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
ntfs_init,
NULL

View File

@ -38,6 +38,13 @@
#define _SYS_MOUNT_H_
#include <sys/ucred.h>
#ifndef KERNEL
#if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)
#include <sys/stat.h>
#endif /* !_POSIX_C_SOURCE */
#endif /* !KERNEL */
#include <sys/queue.h>
#include <sys/lock.h>
@ -305,8 +312,9 @@ struct vfsops {
int (*vfs_vget) __P((struct mount *mp, ino_t ino,
struct vnode **vpp));
int (*vfs_fhtovp) __P((struct mount *mp, struct fid *fhp,
struct sockaddr *nam, struct vnode **vpp,
int *exflagsp, struct ucred **credanonp));
struct vnode **vpp));
int (*vfs_checkexp) __P((struct mount *mp, struct sockaddr *nam,
int *extflagsp, struct ucred **credanonp));
int (*vfs_vptofh) __P((struct vnode *vp, struct fid *fhp));
int (*vfs_init) __P((struct vfsconf *));
int (*vfs_uninit) __P((struct vfsconf *));
@ -321,9 +329,11 @@ struct vfsops {
#define VFS_STATFS(MP, SBP, P) (*(MP)->mnt_op->vfs_statfs)(MP, SBP, P)
#define VFS_SYNC(MP, WAIT, C, P) (*(MP)->mnt_op->vfs_sync)(MP, WAIT, C, P)
#define VFS_VGET(MP, INO, VPP) (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP)
#define VFS_FHTOVP(MP, FIDP, NAM, VPP, EXFLG, CRED) \
(*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, NAM, VPP, EXFLG, CRED)
#define VFS_FHTOVP(MP, FIDP, VPP) \
(*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP)
#define VFS_VPTOFH(VP, FIDP) (*(VP)->v_mount->mnt_op->vfs_vptofh)(VP, FIDP)
#define VFS_CHECKEXP(MP, NAM, EXFLG, CRED) \
(*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED)
#include <sys/module.h>
@ -409,8 +419,9 @@ int vfs_stdstatfs __P((struct mount *mp, struct statfs *sbp, struct proc *p));
int vfs_stdsync __P((struct mount *mp, int waitfor, struct ucred *cred,
struct proc *p));
int vfs_stdvget __P((struct mount *mp, ino_t ino, struct vnode **vpp));
int vfs_stdfhtovp __P((struct mount *mp, struct fid *fhp, struct sockaddr *nam,
struct vnode **vpp, int *exflagsp, struct ucred **credanonp));
int vfs_stdfhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
int vfs_stdcheckexp __P((struct mount *mp, struct sockaddr *nam,
int *extflagsp, struct ucred **credanonp));
int vfs_stdvptofh __P((struct vnode *vp, struct fid *fhp));
int vfs_stdinit __P((struct vfsconf *));
int vfs_stduninit __P((struct vfsconf *));
@ -427,6 +438,9 @@ int getmntinfo __P((struct statfs **, int));
int mount __P((const char *, const char *, int, void *));
int statfs __P((const char *, struct statfs *));
int unmount __P((const char *, int));
int fhopen __P((const struct fhandle *, int));
int fhstat __P((const struct fhandle *, struct stat *));
int fhstatfs __P((const struct fhandle *, struct statfs *));
/* C library stuff */
void endvfsent __P((void));

View File

@ -2,6 +2,7 @@
* System call hiders.
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.63 1999/08/28 00:46:19 peter Exp
*/
@ -216,6 +217,9 @@ HIDE_BSD(msync)
HIDE_BSD(nstat)
HIDE_BSD(nfstat)
HIDE_BSD(nlstat)
HIDE_BSD(fhstatfs)
HIDE_BSD(fhopen)
HIDE_BSD(fhstat)
HIDE_BSD(modnext)
HIDE_BSD(modstat)
HIDE_BSD(modfnext)

View File

@ -2,6 +2,7 @@
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.63 1999/08/28 00:46:19 peter Exp
*/
@ -221,6 +222,9 @@
#define SYS_nstat 278
#define SYS_nfstat 279
#define SYS_nlstat 280
#define SYS_fhstatfs 297
#define SYS_fhopen 298
#define SYS_fhstat 299
#define SYS_modnext 300
#define SYS_modstat 301
#define SYS_modfnext 302

View File

@ -1,5 +1,6 @@
# FreeBSD system call names.
# DO NOT EDIT-- this file is automatically generated.
# $FreeBSD$
# created from FreeBSD: src/sys/kern/syscalls.master,v 1.63 1999/08/28 00:46:19 peter Exp
MIASM = \
syscall.o \
@ -178,6 +179,9 @@ MIASM = \
nstat.o \
nfstat.o \
nlstat.o \
fhstatfs.o \
fhopen.o \
fhstat.o \
modnext.o \
modstat.o \
modfnext.o \

View File

@ -2,6 +2,7 @@
* System call prototypes.
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.63 1999/08/28 00:46:19 peter Exp
*/
@ -779,6 +780,18 @@ struct nlstat_args {
char * path; char path_[PAD_(char *)];
struct nstat * ub; char ub_[PAD_(struct nstat *)];
};
struct fhstatfs_args {
const struct fhandle * u_fhp; char u_fhp_[PAD_(const struct fhandle *)];
struct statfs * buf; char buf_[PAD_(struct statfs *)];
};
struct fhopen_args {
const struct fhandle * u_fhp; char u_fhp_[PAD_(const struct fhandle *)];
int flags; char flags_[PAD_(int)];
};
struct fhstat_args {
const struct fhandle * u_fhp; char u_fhp_[PAD_(const struct fhandle *)];
struct stat * sb; char sb_[PAD_(struct stat *)];
};
struct modnext_args {
int modid; char modid_[PAD_(int)];
};
@ -1084,6 +1097,9 @@ int lutimes __P((struct proc *, struct lutimes_args *));
int nstat __P((struct proc *, struct nstat_args *));
int nfstat __P((struct proc *, struct nfstat_args *));
int nlstat __P((struct proc *, struct nlstat_args *));
int fhstatfs __P((struct proc *, struct fhstatfs_args *));
int fhopen __P((struct proc *, struct fhopen_args *));
int fhstat __P((struct proc *, struct fhstat_args *));
int modnext __P((struct proc *, struct modnext_args *));
int modstat __P((struct proc *, struct modstat_args *));
int modfnext __P((struct proc *, struct modfnext_args *));

View File

@ -76,8 +76,9 @@ void ffs_blkfree __P((struct inode *, ufs_daddr_t, long));
ufs_daddr_t ffs_blkpref __P((struct inode *, ufs_daddr_t, int, ufs_daddr_t *));
int ffs_bmap __P((struct vop_bmap_args *));
void ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t));
int ffs_fhtovp __P((struct mount *, struct fid *, struct sockaddr *,
struct vnode **, int *, struct ucred **));
int ffs_fhtovp __P((struct mount *, struct fid *, struct vnode **));
int ffs_checkexp __P((struct mount *, struct sockaddr *, int *,
struct ucred **));
int ffs_flushfiles __P((struct mount *, int, struct proc *));
void ffs_fragacct __P((struct fs *, int, int32_t [], int));
int ffs_freefile __P(( struct vnode *, ino_t, int ));

View File

@ -80,6 +80,7 @@ static struct vfsops ufs_vfsops = {
ffs_sync,
ffs_vget,
ffs_fhtovp,
ufs_check_export,
ffs_vptofh,
ffs_init,
};
@ -1177,13 +1178,10 @@ ffs_vget(mp, ino, vpp)
* those rights via. exflagsp and credanonp
*/
int
ffs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
ffs_fhtovp(mp, fhp, vpp)
register struct mount *mp;
struct fid *fhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
register struct ufid *ufhp;
struct fs *fs;
@ -1193,7 +1191,7 @@ ffs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
if (ufhp->ufid_ino < ROOTINO ||
ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg)
return (ESTALE);
return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp));
return (ufs_fhtovp(mp, ufhp, vpp));
}
/*

View File

@ -114,6 +114,7 @@ static struct vfsops mfs_vfsops = {
ffs_sync,
ffs_vget,
ffs_fhtovp,
ufs_check_export,
ffs_vptofh,
mfs_init,
};

View File

@ -61,9 +61,9 @@ int ufs_vnoperatespec __P((struct vop_generic_args *));
int ufs_bmap __P((struct vop_bmap_args *));
int ufs_bmaparray __P((struct vnode *, daddr_t, daddr_t *, struct indir *,
int *, int *, int *));
int ufs_check_export __P((struct mount *, struct ufid *,
struct sockaddr *, struct vnode **,
int *exflagsp, struct ucred **));
int ufs_check_export __P((struct mount *, struct sockaddr *,
int *, struct ucred **));
int ufs_fhtovp(register struct mount *, struct ufid *, struct vnode **);
int ufs_checkpath __P((struct inode *, struct inode *, struct ucred *));
void ufs_dirbad __P((struct inode *, doff_t, char *));
int ufs_dirbadentry __P((struct vnode *, struct direct *, int));

View File

@ -183,31 +183,18 @@ ufs_init(vfsp)
* This is the generic part of fhtovp called after the underlying
* filesystem has validated the file handle.
*
* Verify that a host should have access to a filesystem, and if so
* return a vnode for the presented file handle.
* Call the VFS_CHECKEXP beforehand to verify access.
*/
int
ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)
ufs_fhtovp(mp, ufhp, vpp)
register struct mount *mp;
struct ufid *ufhp;
struct sockaddr *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
register struct inode *ip;
register struct netcred *np;
register struct ufsmount *ump = VFSTOUFS(mp);
struct vnode *nvp;
int error;
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &ump->um_export, nam);
if (np == NULL)
return (EACCES);
error = VFS_VGET(mp, ufhp->ufid_ino, &nvp);
if (error) {
*vpp = NULLVP;
@ -220,6 +207,34 @@ ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)
return (ESTALE);
}
*vpp = nvp;
return (0);
}
/*
* This is the generic part of fhtovp called after the underlying
* filesystem has validated the file handle.
*
* Verify that a host should have access to a filesystem.
*/
int
ufs_check_export(mp, nam, exflagsp, credanonp)
register struct mount *mp;
struct sockaddr *nam;
int *exflagsp;
struct ucred **credanonp;
{
register struct netcred *np;
register struct ufsmount *ump;;
ump = VFSTOUFS(mp);
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &ump->um_export, nam);
if (np == NULL)
return (EACCES);
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return (0);