From 79e57264acfef7469f564d0a53bb70eebc2b4026 Mon Sep 17 00:00:00 2001 From: phk Date: Sun, 20 Aug 2000 08:36:26 +0000 Subject: [PATCH] Centralize the canonical vop_access user/group/other check in vaccess(). Discussed with: bde --- sys/fs/cd9660/cd9660_vnops.c | 45 ++------------------------ sys/fs/hpfs/hpfs_vnops.c | 44 ++------------------------ sys/fs/msdosfs/msdosfs_vnops.c | 44 ++------------------------ sys/fs/ntfs/ntfs_vnops.c | 46 +++------------------------ sys/isofs/cd9660/cd9660_vnops.c | 45 ++------------------------ sys/kern/vfs_export.c | 54 ++++++++++++++++++++++++++++++++ sys/kern/vfs_subr.c | 54 ++++++++++++++++++++++++++++++++ sys/miscfs/kernfs/kernfs_vnops.c | 29 +---------------- sys/msdosfs/msdosfs_vnops.c | 44 ++------------------------ sys/ntfs/ntfs_vnops.c | 46 +++------------------------ sys/sys/vnode.h | 2 ++ sys/ufs/ufs/ufs_vnops.c | 44 ++------------------------ 12 files changed, 137 insertions(+), 360 deletions(-) diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index e4c6909af795..b4e06fb5d9ad 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -135,10 +135,7 @@ cd9660_access(ap) { struct vnode *vp = ap->a_vp; struct iso_node *ip = VTOI(vp); - struct ucred *cred = ap->a_cred; - mode_t mask, mode = ap->a_mode; - gid_t *gp; - int i; + mode_t mode = ap->a_mode; /* * Disallow write attempts unless the file is a socket, @@ -157,44 +154,8 @@ cd9660_access(ap) } } - /* User id 0 always gets access. */ - if (cred->cr_uid == 0) - return (0); - - mask = 0; - - /* Otherwise, check the owner. */ - if (cred->cr_uid == ip->inode.iso_uid) { - if (mode & VEXEC) - mask |= S_IXUSR; - if (mode & VREAD) - mask |= S_IRUSR; - if (mode & VWRITE) - mask |= S_IWUSR; - return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check the groups. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (ip->inode.iso_gid == *gp) { - if (mode & VEXEC) - mask |= S_IXGRP; - if (mode & VREAD) - mask |= S_IRGRP; - if (mode & VWRITE) - mask |= S_IWGRP; - return ((ip->inode.iso_mode & mask) == mask ? - 0 : EACCES); - } - - /* Otherwise, check everyone else. */ - if (mode & VEXEC) - mask |= S_IXOTH; - if (mode & VREAD) - mask |= S_IROTH; - if (mode & VWRITE) - mask |= S_IWOTH; - return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); + return (vaccess(vp->v_type, ip->inode.iso_mode, ip->inode.iso_uid, + ip->inode.iso_gid, ap->a_mode, ap->a_cred)); } static int diff --git a/sys/fs/hpfs/hpfs_vnops.c b/sys/fs/hpfs/hpfs_vnops.c index 4ab248c57669..4f5a7354c665 100644 --- a/sys/fs/hpfs/hpfs_vnops.c +++ b/sys/fs/hpfs/hpfs_vnops.c @@ -777,10 +777,7 @@ hpfs_access(ap) { struct vnode *vp = ap->a_vp; struct hpfsnode *hp = VTOHP(vp); - struct ucred *cred = ap->a_cred; - mode_t mask, mode = ap->a_mode; - register gid_t *gp; - int i; + mode_t mode = ap->a_mode; dprintf(("hpfs_access(0x%x):\n", hp->h_no)); @@ -800,43 +797,8 @@ hpfs_access(ap) } } - /* Otherwise, user id 0 always gets access. */ - if (cred->cr_uid == 0) - return (0); - - mask = 0; - - /* Otherwise, check the owner. */ - if (cred->cr_uid == hp->h_uid) { - if (mode & VEXEC) - mask |= S_IXUSR; - if (mode & VREAD) - mask |= S_IRUSR; - if (mode & VWRITE) - mask |= S_IWUSR; - return ((hp->h_mode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check the groups. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (hp->h_gid == *gp) { - if (mode & VEXEC) - mask |= S_IXGRP; - if (mode & VREAD) - mask |= S_IRGRP; - if (mode & VWRITE) - mask |= S_IWGRP; - return ((hp->h_mode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check everyone else. */ - if (mode & VEXEC) - mask |= S_IXOTH; - if (mode & VREAD) - mask |= S_IROTH; - if (mode & VWRITE) - mask |= S_IWOTH; - return ((hp->h_mode & mask) == mask ? 0 : EACCES); + return (vaccess(vp->v_type, hp->h_mode, hp->h_uid, hp->h_gid, + ap->a_mode, ap->a_cred)); } /* diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 10ebaf869497..09f99e39d87f 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -252,10 +252,7 @@ msdosfs_access(ap) struct vnode *vp = ap->a_vp; struct denode *dep = VTODE(ap->a_vp); struct msdosfsmount *pmp = dep->de_pmp; - struct ucred *cred = ap->a_cred; - mode_t mask, file_mode, mode = ap->a_mode; - register gid_t *gp; - int i; + mode_t file_mode, mode = ap->a_mode; file_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) | ((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH)); @@ -279,43 +276,8 @@ msdosfs_access(ap) } } - /* User id 0 always gets access. */ - if (cred->cr_uid == 0) - return 0; - - mask = 0; - - /* Otherwise, check the owner. */ - if (cred->cr_uid == pmp->pm_uid) { - if (mode & VEXEC) - mask |= S_IXUSR; - if (mode & VREAD) - mask |= S_IRUSR; - if (mode & VWRITE) - mask |= S_IWUSR; - return (file_mode & mask) == mask ? 0 : EACCES; - } - - /* Otherwise, check the groups. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (pmp->pm_gid == *gp) { - if (mode & VEXEC) - mask |= S_IXGRP; - if (mode & VREAD) - mask |= S_IRGRP; - if (mode & VWRITE) - mask |= S_IWGRP; - return (file_mode & mask) == mask ? 0 : EACCES; - } - - /* Otherwise, check everyone else. */ - if (mode & VEXEC) - mask |= S_IXOTH; - if (mode & VREAD) - mask |= S_IROTH; - if (mode & VWRITE) - mask |= S_IWOTH; - return (file_mode & mask) == mask ? 0 : EACCES; + return (vaccess(vp->v_type, file_mode, pmp->pm_uid, pmp->pm_gid, + ap->a_mode, ap->a_cred)); } static int diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c index e3db31f8d3ab..06dab1c50c27 100644 --- a/sys/fs/ntfs/ntfs_vnops.c +++ b/sys/fs/ntfs/ntfs_vnops.c @@ -450,10 +450,7 @@ ntfs_access(ap) { struct vnode *vp = ap->a_vp; struct ntnode *ip = VTONT(vp); - struct ucred *cred = ap->a_cred; - mode_t mask, mode = ap->a_mode; - register gid_t *gp; - int i; + mode_t mode = ap->a_mode; #ifdef QUOTA int error; #endif @@ -480,44 +477,9 @@ ntfs_access(ap) } } - /* Otherwise, user id 0 always gets access. */ - if (cred->cr_uid == 0) - return (0); - - mask = 0; - - /* Otherwise, check the owner. */ - if (cred->cr_uid == ip->i_mp->ntm_uid) { - if (mode & VEXEC) - mask |= S_IXUSR; - if (mode & VREAD) - mask |= S_IRUSR; - if (mode & VWRITE) - mask |= S_IWUSR; - return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check the groups. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (ip->i_mp->ntm_gid == *gp) { - if (mode & VEXEC) - mask |= S_IXGRP; - if (mode & VREAD) - mask |= S_IRGRP; - if (mode & VWRITE) - mask |= S_IWGRP; - return ((ip->i_mp->ntm_mode&mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check everyone else. */ - if (mode & VEXEC) - mask |= S_IXOTH; - if (mode & VREAD) - mask |= S_IROTH; - if (mode & VWRITE) - mask |= S_IWOTH; - return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES); -} + return (vaccess(vp->v_type, ip->i_mp->ntm_mode, ip->i_mp->ntm_uid, + ip->i_mp->ntm_gid, ap->a_mode, ap->a_cred)); +} /* * Open called. diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c index e4c6909af795..b4e06fb5d9ad 100644 --- a/sys/isofs/cd9660/cd9660_vnops.c +++ b/sys/isofs/cd9660/cd9660_vnops.c @@ -135,10 +135,7 @@ cd9660_access(ap) { struct vnode *vp = ap->a_vp; struct iso_node *ip = VTOI(vp); - struct ucred *cred = ap->a_cred; - mode_t mask, mode = ap->a_mode; - gid_t *gp; - int i; + mode_t mode = ap->a_mode; /* * Disallow write attempts unless the file is a socket, @@ -157,44 +154,8 @@ cd9660_access(ap) } } - /* User id 0 always gets access. */ - if (cred->cr_uid == 0) - return (0); - - mask = 0; - - /* Otherwise, check the owner. */ - if (cred->cr_uid == ip->inode.iso_uid) { - if (mode & VEXEC) - mask |= S_IXUSR; - if (mode & VREAD) - mask |= S_IRUSR; - if (mode & VWRITE) - mask |= S_IWUSR; - return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check the groups. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (ip->inode.iso_gid == *gp) { - if (mode & VEXEC) - mask |= S_IXGRP; - if (mode & VREAD) - mask |= S_IRGRP; - if (mode & VWRITE) - mask |= S_IWGRP; - return ((ip->inode.iso_mode & mask) == mask ? - 0 : EACCES); - } - - /* Otherwise, check everyone else. */ - if (mode & VEXEC) - mask |= S_IXOTH; - if (mode & VREAD) - mask |= S_IROTH; - if (mode & VWRITE) - mask |= S_IWOTH; - return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); + return (vaccess(vp->v_type, ip->inode.iso_mode, ip->inode.iso_uid, + ip->inode.iso_gid, ap->a_mode, ap->a_cred)); } static int diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index db16d9fe6080..d9c4260f4ae3 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -2984,3 +2984,57 @@ NDFREE(ndp, flags) ndp->ni_startdir = NULL; } } + +int +vaccess(type, file_mode, uid, gid, acc_mode, cred) + enum vtype type; + mode_t file_mode; + uid_t uid; + gid_t gid; + mode_t acc_mode; + struct ucred *cred; +{ + mode_t mask; + + /* + * At this point, uid == 0 can do anything. + * XXX: should use suser() ? */ + * XXX: Should only check root-ness after other checks fail. + */ + if (cred->cr_uid == 0) + return (0); + + mask = 0; + + /* Otherwise, check the owner. */ + if (cred->cr_uid == uid) { + if (acc_mode & VEXEC) + mask |= S_IXUSR; + if (acc_mode & VREAD) + mask |= S_IRUSR; + if (acc_mode & VWRITE) + mask |= S_IWUSR; + return ((file_mode & mask) == mask ? 0 : EACCES); + } + + /* Otherwise, check for all groups. */ + if (groupmember(gid, cred)) { + if (acc_mode & VEXEC) + mask |= S_IXGRP; + if (acc_mode & VREAD) + mask |= S_IRGRP; + if (acc_mode & VWRITE) + mask |= S_IWGRP; + return ((file_mode & mask) == mask ? 0 : EACCES); + } + + /* Otherwise, check everyone else. */ + if (acc_mode & VEXEC) + mask |= S_IXOTH; + if (acc_mode & VREAD) + mask |= S_IROTH; + if (acc_mode & VWRITE) + mask |= S_IWOTH; + return ((file_mode & mask) == mask ? 0 : EACCES); +} + diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index db16d9fe6080..d9c4260f4ae3 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2984,3 +2984,57 @@ NDFREE(ndp, flags) ndp->ni_startdir = NULL; } } + +int +vaccess(type, file_mode, uid, gid, acc_mode, cred) + enum vtype type; + mode_t file_mode; + uid_t uid; + gid_t gid; + mode_t acc_mode; + struct ucred *cred; +{ + mode_t mask; + + /* + * At this point, uid == 0 can do anything. + * XXX: should use suser() ? */ + * XXX: Should only check root-ness after other checks fail. + */ + if (cred->cr_uid == 0) + return (0); + + mask = 0; + + /* Otherwise, check the owner. */ + if (cred->cr_uid == uid) { + if (acc_mode & VEXEC) + mask |= S_IXUSR; + if (acc_mode & VREAD) + mask |= S_IRUSR; + if (acc_mode & VWRITE) + mask |= S_IWUSR; + return ((file_mode & mask) == mask ? 0 : EACCES); + } + + /* Otherwise, check for all groups. */ + if (groupmember(gid, cred)) { + if (acc_mode & VEXEC) + mask |= S_IXGRP; + if (acc_mode & VREAD) + mask |= S_IRGRP; + if (acc_mode & VWRITE) + mask |= S_IWGRP; + return ((file_mode & mask) == mask ? 0 : EACCES); + } + + /* Otherwise, check everyone else. */ + if (acc_mode & VEXEC) + mask |= S_IXOTH; + if (acc_mode & VREAD) + mask |= S_IROTH; + if (acc_mode & VWRITE) + mask |= S_IWOTH; + return ((file_mode & mask) == mask ? 0 : EACCES); +} + diff --git a/sys/miscfs/kernfs/kernfs_vnops.c b/sys/miscfs/kernfs/kernfs_vnops.c index f457541f9450..283167abc5fa 100644 --- a/sys/miscfs/kernfs/kernfs_vnops.c +++ b/sys/miscfs/kernfs/kernfs_vnops.c @@ -305,42 +305,15 @@ kernfs_access(ap) } */ *ap; { register struct vnode *vp = ap->a_vp; - register struct ucred *cred = ap->a_cred; mode_t amode = ap->a_mode; mode_t fmode = (vp->v_flag & VROOT) ? DIR_MODE : VTOKERN(vp)->kf_kt->kt_mode; - mode_t mask = 0; - register gid_t *gp; - int i; /* Some files are simply not modifiable. */ if ((amode & VWRITE) && (fmode & (S_IWUSR|S_IWGRP|S_IWOTH)) == 0) return (EPERM); - /* Root can do anything else. */ - if (cred->cr_uid == 0) - return (0); - - /* Check for group 0 (wheel) permissions. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (*gp == 0) { - if (amode & VEXEC) - mask |= S_IXGRP; - if (amode & VREAD) - mask |= S_IRGRP; - if (amode & VWRITE) - mask |= S_IWGRP; - return ((fmode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check everyone else. */ - if (amode & VEXEC) - mask |= S_IXOTH; - if (amode & VREAD) - mask |= S_IROTH; - if (amode & VWRITE) - mask |= S_IWOTH; - return ((fmode & mask) == mask ? 0 : EACCES); + return (vaccess(vp->v_tag, fmode, 0, 0, ap->a_mode, ap->a_cred)); } static int diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c index 10ebaf869497..09f99e39d87f 100644 --- a/sys/msdosfs/msdosfs_vnops.c +++ b/sys/msdosfs/msdosfs_vnops.c @@ -252,10 +252,7 @@ msdosfs_access(ap) struct vnode *vp = ap->a_vp; struct denode *dep = VTODE(ap->a_vp); struct msdosfsmount *pmp = dep->de_pmp; - struct ucred *cred = ap->a_cred; - mode_t mask, file_mode, mode = ap->a_mode; - register gid_t *gp; - int i; + mode_t file_mode, mode = ap->a_mode; file_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) | ((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH)); @@ -279,43 +276,8 @@ msdosfs_access(ap) } } - /* User id 0 always gets access. */ - if (cred->cr_uid == 0) - return 0; - - mask = 0; - - /* Otherwise, check the owner. */ - if (cred->cr_uid == pmp->pm_uid) { - if (mode & VEXEC) - mask |= S_IXUSR; - if (mode & VREAD) - mask |= S_IRUSR; - if (mode & VWRITE) - mask |= S_IWUSR; - return (file_mode & mask) == mask ? 0 : EACCES; - } - - /* Otherwise, check the groups. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (pmp->pm_gid == *gp) { - if (mode & VEXEC) - mask |= S_IXGRP; - if (mode & VREAD) - mask |= S_IRGRP; - if (mode & VWRITE) - mask |= S_IWGRP; - return (file_mode & mask) == mask ? 0 : EACCES; - } - - /* Otherwise, check everyone else. */ - if (mode & VEXEC) - mask |= S_IXOTH; - if (mode & VREAD) - mask |= S_IROTH; - if (mode & VWRITE) - mask |= S_IWOTH; - return (file_mode & mask) == mask ? 0 : EACCES; + return (vaccess(vp->v_type, file_mode, pmp->pm_uid, pmp->pm_gid, + ap->a_mode, ap->a_cred)); } static int diff --git a/sys/ntfs/ntfs_vnops.c b/sys/ntfs/ntfs_vnops.c index e3db31f8d3ab..06dab1c50c27 100644 --- a/sys/ntfs/ntfs_vnops.c +++ b/sys/ntfs/ntfs_vnops.c @@ -450,10 +450,7 @@ ntfs_access(ap) { struct vnode *vp = ap->a_vp; struct ntnode *ip = VTONT(vp); - struct ucred *cred = ap->a_cred; - mode_t mask, mode = ap->a_mode; - register gid_t *gp; - int i; + mode_t mode = ap->a_mode; #ifdef QUOTA int error; #endif @@ -480,44 +477,9 @@ ntfs_access(ap) } } - /* Otherwise, user id 0 always gets access. */ - if (cred->cr_uid == 0) - return (0); - - mask = 0; - - /* Otherwise, check the owner. */ - if (cred->cr_uid == ip->i_mp->ntm_uid) { - if (mode & VEXEC) - mask |= S_IXUSR; - if (mode & VREAD) - mask |= S_IRUSR; - if (mode & VWRITE) - mask |= S_IWUSR; - return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check the groups. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (ip->i_mp->ntm_gid == *gp) { - if (mode & VEXEC) - mask |= S_IXGRP; - if (mode & VREAD) - mask |= S_IRGRP; - if (mode & VWRITE) - mask |= S_IWGRP; - return ((ip->i_mp->ntm_mode&mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check everyone else. */ - if (mode & VEXEC) - mask |= S_IXOTH; - if (mode & VREAD) - mask |= S_IROTH; - if (mode & VWRITE) - mask |= S_IWOTH; - return ((ip->i_mp->ntm_mode & mask) == mask ? 0 : EACCES); -} + return (vaccess(vp->v_type, ip->i_mp->ntm_mode, ip->i_mp->ntm_uid, + ip->i_mp->ntm_gid, ap->a_mode, ap->a_cred)); +} /* * Open called. diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 82c4d1e84ca3..a6f234d80bc0 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -554,6 +554,8 @@ int lease_check __P((struct vop_lease_args *ap)); int spec_vnoperate __P((struct vop_generic_args *)); int speedup_syncer __P((void)); int textvp_fullpath __P((struct proc *p, char **retbuf, char **retfreebuf)); +int vaccess __P((enum vtype type, mode_t file_mode, uid_t uid, gid_t gid, + mode_t acc_mode, struct ucred *cred)); void vattr_null __P((struct vattr *vap)); int vcount __P((struct vnode *vp)); void vdrop __P((struct vnode *)); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 0c2da7d50e2e..298c1339ce4a 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -300,10 +300,7 @@ ufs_access(ap) { struct vnode *vp = ap->a_vp; struct inode *ip = VTOI(vp); - struct ucred *cred = ap->a_cred; - mode_t mask, mode = ap->a_mode; - register gid_t *gp; - int i; + mode_t mode = ap->a_mode; #ifdef QUOTA int error; #endif @@ -334,43 +331,8 @@ ufs_access(ap) if ((mode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT))) return (EPERM); - /* Otherwise, user id 0 always gets access. */ - if (cred->cr_uid == 0) - return (0); - - mask = 0; - - /* Otherwise, check the owner. */ - if (cred->cr_uid == ip->i_uid) { - if (mode & VEXEC) - mask |= S_IXUSR; - if (mode & VREAD) - mask |= S_IRUSR; - if (mode & VWRITE) - mask |= S_IWUSR; - return ((ip->i_mode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check the groups. */ - for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) - if (ip->i_gid == *gp) { - if (mode & VEXEC) - mask |= S_IXGRP; - if (mode & VREAD) - mask |= S_IRGRP; - if (mode & VWRITE) - mask |= S_IWGRP; - return ((ip->i_mode & mask) == mask ? 0 : EACCES); - } - - /* Otherwise, check everyone else. */ - if (mode & VEXEC) - mask |= S_IXOTH; - if (mode & VREAD) - mask |= S_IROTH; - if (mode & VWRITE) - mask |= S_IWOTH; - return ((ip->i_mode & mask) == mask ? 0 : EACCES); + return (vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, + ap->a_mode, ap->a_cred)); } /* ARGSUSED */