Author: trasz
Date: Sat May 30 13:59:05 2009
New Revision: 193092
URL: http://svn.freebsd.org/changeset/base/193092

Log:
  Add VOP_ACCESSX, which can be used to query for newly added V*
  permissions, such as VWRITE_ACL.  For a filsystems that don't
  implement it, there is a default implementation, which works
  as a wrapper around VOP_ACCESS.
  
  Reviewed by:  rwatson@

Modified:
  head/share/man/man9/Makefile
  head/share/man/man9/VOP_ACCESS.9
  head/sys/fs/nullfs/null_vnops.c
  head/sys/kern/vfs_default.c
  head/sys/kern/vfs_subr.c
  head/sys/kern/vnode_if.src
  head/sys/sys/vnode.h

Modified: head/share/man/man9/Makefile
==============================================================================
--- head/share/man/man9/Makefile        Sat May 30 12:26:11 2009        
(r193091)
+++ head/share/man/man9/Makefile        Sat May 30 13:59:05 2009        
(r193092)
@@ -1288,6 +1288,7 @@ MLINKS+=vm_page_io.9 vm_page_io_finish.9
 MLINKS+=vm_page_wakeup.9 vm_page_busy.9 \
        vm_page_wakeup.9 vm_page_flash.9
 MLINKS+=vm_page_wire.9 vm_page_unwire.9
+MLINKS+=VOP_ACCESS.9 VOP_ACCESSX.9
 MLINKS+=VOP_ATTRIB.9 VOP_GETATTR.9 \
        VOP_ATTRIB.9 VOP_SETATTR.9
 MLINKS+=VOP_CREATE.9 VOP_MKDIR.9 \

Modified: head/share/man/man9/VOP_ACCESS.9
==============================================================================
--- head/share/man/man9/VOP_ACCESS.9    Sat May 30 12:26:11 2009        
(r193091)
+++ head/share/man/man9/VOP_ACCESS.9    Sat May 30 13:59:05 2009        
(r193092)
@@ -29,17 +29,20 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 24, 1996
+.Dd May 30, 2009
 .Os
 .Dt VOP_ACCESS 9
 .Sh NAME
-.Nm VOP_ACCESS
+.Nm VOP_ACCESS ,
+.Nm VOP_ACCESSX
 .Nd "check access permissions of a file or Unix domain socket"
 .Sh SYNOPSIS
 .In sys/param.h
 .In sys/vnode.h
 .Ft int
 .Fn VOP_ACCESS "struct vnode *vp" "accmode_t accmode" "struct ucred *cred" 
"struct thread *td"
+.Ft int
+.Fn VOP_ACCESSX "struct vnode *vp" "accmode_t accmode" "struct ucred *cred" 
"struct thread *td"
 .Sh DESCRIPTION
 This entry point checks the access permissions of the file against the
 given credentials.
@@ -63,6 +66,20 @@ is a mask which can contain flags descri
 .Dv VWRITE
 or
 .Dv VEXEC .
+For
+.Fn VOP_ACCESS ,
+the only flags that may be set in
+.Fa accmode
+are
+.Dv VEXEC ,
+.Dv VWRITE ,
+.Dv VREAD ,
+.Dv VADMIN
+and
+.Dv VAPPEND .
+To check for other bits, one has to use
+.Fn VOP_ACCESSX
+instead.
 .Sh LOCKS
 The vnode will be locked on entry and should remain locked on return.
 .Sh RETURN VALUES

Modified: head/sys/fs/nullfs/null_vnops.c
==============================================================================
--- head/sys/fs/nullfs/null_vnops.c     Sat May 30 12:26:11 2009        
(r193091)
+++ head/sys/fs/nullfs/null_vnops.c     Sat May 30 13:59:05 2009        
(r193092)
@@ -472,6 +472,32 @@ null_access(struct vop_access_args *ap)
        return (null_bypass((struct vop_generic_args *)ap));
 }
 
+static int
+null_accessx(struct vop_accessx_args *ap)
+{
+       struct vnode *vp = ap->a_vp;
+       accmode_t accmode = ap->a_accmode;
+
+       /*
+        * Disallow write attempts on read-only layers;
+        * unless the file is a socket, fifo, or a block or
+        * character device resident on the filesystem.
+        */
+       if (accmode & VWRITE) {
+               switch (vp->v_type) {
+               case VDIR:
+               case VLNK:
+               case VREG:
+                       if (vp->v_mount->mnt_flag & MNT_RDONLY)
+                               return (EROFS);
+                       break;
+               default:
+                       break;
+               }
+       }
+       return (null_bypass((struct vop_generic_args *)ap));
+}
+
 /*
  * We handle this to eliminate null FS to lower FS
  * file moving. Don't know why we don't allow this,
@@ -720,6 +746,7 @@ null_vptofh(struct vop_vptofh_args *ap)
 struct vop_vector null_vnodeops = {
        .vop_bypass =           null_bypass,
        .vop_access =           null_access,
+       .vop_accessx =          null_accessx,
        .vop_bmap =             VOP_EOPNOTSUPP,
        .vop_getattr =          null_getattr,
        .vop_getwritemount =    null_getwritemount,

Modified: head/sys/kern/vfs_default.c
==============================================================================
--- head/sys/kern/vfs_default.c Sat May 30 12:26:11 2009        (r193091)
+++ head/sys/kern/vfs_default.c Sat May 30 13:59:05 2009        (r193092)
@@ -87,6 +87,7 @@ struct vop_vector default_vnodeops = {
        .vop_default =          NULL,
        .vop_bypass =           VOP_EOPNOTSUPP,
 
+       .vop_accessx =          vop_stdaccessx,
        .vop_advlock =          vop_stdadvlock,
        .vop_advlockasync =     vop_stdadvlockasync,
        .vop_bmap =             vop_stdbmap,
@@ -322,6 +323,22 @@ out:
        return (found);
 }
 
+int
+vop_stdaccessx(struct vop_accessx_args *ap)
+{
+       int error;
+       accmode_t accmode = ap->a_accmode;
+
+       error = vfs_unixify_accmode(&accmode);
+       if (error != 0)
+               return (error);
+
+       if (accmode == 0)
+               return (0);
+
+       return (VOP_ACCESS(ap->a_vp, accmode, ap->a_cred, ap->a_td));
+}
+
 /*
  * Advisory record locking support
  */

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c    Sat May 30 12:26:11 2009        (r193091)
+++ head/sys/kern/vfs_subr.c    Sat May 30 13:59:05 2009        (r193092)
@@ -4253,3 +4253,50 @@ vfs_mark_atime(struct vnode *vp, struct 
        if ((vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0)
                (void)VOP_MARKATIME(vp);
 }
+
+/*
+ * The purpose of this routine is to remove granularity from accmode_t,
+ * reducing it into standard unix access bits - VEXEC, VREAD, VWRITE,
+ * VADMIN and VAPPEND.
+ *
+ * If it returns 0, the caller is supposed to continue with the usual
+ * access checks using 'accmode' as modified by this routine.  If it
+ * returns nonzero value, the caller is supposed to return that value
+ * as errno.
+ *
+ * Note that after this routine runs, accmode may be zero.
+ */
+int
+vfs_unixify_accmode(accmode_t *accmode)
+{
+       /*
+        * There is no way to specify explicit "deny" rule using
+        * file mode or POSIX.1e ACLs.
+        */
+       if (*accmode & VEXPLICIT_DENY) {
+               *accmode = 0;
+               return (0);
+       }
+
+       /*
+        * None of these can be translated into usual access bits.
+        * Also, the common case for NFSv4 ACLs is to not contain
+        * either of these bits. Caller should check for VWRITE
+        * on the containing directory instead.
+        */
+       if (*accmode & (VDELETE_CHILD | VDELETE))
+               return (EPERM);
+
+       if (*accmode & VADMIN_PERMS) {
+               *accmode &= ~VADMIN_PERMS;
+               *accmode |= VADMIN;
+       }
+
+       /*
+        * There is no way to deny VREAD_ATTRIBUTES, VREAD_ACL
+        * or VSYNCHRONIZE using file mode or POSIX.1e ACL.
+        */
+       *accmode &= ~(VSTAT_PERMS | VSYNCHRONIZE);
+
+       return (0);
+}

Modified: head/sys/kern/vnode_if.src
==============================================================================
--- head/sys/kern/vnode_if.src  Sat May 30 12:26:11 2009        (r193091)
+++ head/sys/kern/vnode_if.src  Sat May 30 13:59:05 2009        (r193092)
@@ -153,6 +153,16 @@ vop_access {
 };
 
 
+%% accessx     vp      L L L
+
+vop_accessx {
+       IN struct vnode *vp;
+       IN accmode_t accmode;
+       IN struct ucred *cred;
+       IN struct thread *td;
+};
+
+
 %% getattr     vp      L L L
 
 vop_getattr {

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h        Sat May 30 12:26:11 2009        (r193091)
+++ head/sys/sys/vnode.h        Sat May 30 13:59:05 2009        (r193092)
@@ -676,6 +676,7 @@ int vop_stdlock(struct vop_lock1_args *)
 int    vop_stdputpages(struct vop_putpages_args *);
 int    vop_stdunlock(struct vop_unlock_args *);
 int    vop_nopoll(struct vop_poll_args *);
+int    vop_stdaccessx(struct vop_accessx_args *ap);
 int    vop_stdadvlock(struct vop_advlock_args *ap);
 int    vop_stdadvlockasync(struct vop_advlockasync_args *ap);
 int    vop_stdpathconf(struct vop_pathconf_args *);
@@ -766,6 +767,8 @@ void vfs_mark_atime(struct vnode *vp, st
 struct dirent;
 int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off);
 
+int    vfs_unixify_accmode(accmode_t *accmode);
+
 #endif /* _KERNEL */
 
 #endif /* !_SYS_VNODE_H_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to