From 0ccdae7b7da6e583cf244fbb3adddf920a68584b Mon Sep 17 00:00:00 2001 From: rmacklem Date: Fri, 25 Dec 2009 20:44:19 +0000 Subject: Modify the experimental server so that it uses VOP_ACCESSX(). This is necessary in order to enable NFSv4 ACL support. The argument to nfsvno_accchk() was changed to an accmode_t and the function nfsrv_aclaccess() was no longer needed and, therefore, deleted. Reviewed by: trasz MFC after: 2 weeks --- sys/fs/nfs/nfs_commonacl.c | 64 ----------------------------------- sys/fs/nfs/nfs_var.h | 6 ++-- sys/fs/nfsserver/nfs_nfsdport.c | 73 ++++++++++++++++++---------------------- sys/fs/nfsserver/nfs_nfsdserv.c | 74 ++++++++++++++++++++++------------------- 4 files changed, 75 insertions(+), 142 deletions(-) diff --git a/sys/fs/nfs/nfs_commonacl.c b/sys/fs/nfs/nfs_commonacl.c index d639cfc..910a6a4 100644 --- a/sys/fs/nfs/nfs_commonacl.c +++ b/sys/fs/nfs/nfs_commonacl.c @@ -437,70 +437,6 @@ nfsrv_buildacl(struct nfsrv_descript *nd, NFSACL_T *aclp, enum vtype type, } /* - * Check access for an NFSv4 acl. - * The vflags are the basic VREAD, VWRITE, VEXEC. The mask is the NFSV4ACE - * mask bits for the more detailed check. - * If the more detailed check fails, due to no acl, do a basic one. - */ -APPLESTATIC int -nfsrv_aclaccess(vnode_t vp, accmode_t vflags, u_int32_t mask, - struct ucred *cred, NFSPROC_T *p) -{ - int error = 0; - accmode_t access; - - if (nfsrv_useacl == 0) { - error = VOP_ACCESS(vp, vflags, cred, p); - return (error); - } - - /* Convert NFSV4ACE mask to vaccess_t */ - access = 0; - if (mask & NFSV4ACE_READDATA) - access |= VREAD; - if (mask & NFSV4ACE_LISTDIRECTORY) - access |= VREAD; - if (mask & NFSV4ACE_WRITEDATA) - access |= VWRITE; - if (mask & NFSV4ACE_ADDFILE) - access |= VWRITE; - if (mask & NFSV4ACE_APPENDDATA) - access |= VAPPEND; - if (mask & NFSV4ACE_ADDSUBDIRECTORY) - access |= VAPPEND; - if (mask & NFSV4ACE_READNAMEDATTR) - access |= VREAD_NAMED_ATTRS; - if (mask & NFSV4ACE_WRITENAMEDATTR) - access |= VWRITE_NAMED_ATTRS; - if (mask & NFSV4ACE_EXECUTE) - access |= VEXEC; - if (mask & NFSV4ACE_SEARCH) - access |= VEXEC; - if (mask & NFSV4ACE_DELETECHILD) - access |= VDELETE_CHILD; - if (mask & NFSV4ACE_READATTRIBUTES) - access |= VREAD_ATTRIBUTES; - if (mask & NFSV4ACE_WRITEATTRIBUTES) - access |= VWRITE_ATTRIBUTES; - if (mask & NFSV4ACE_DELETE) - access |= VDELETE; - if (mask & NFSV4ACE_READACL) - access |= VREAD_ACL; - if (mask & NFSV4ACE_WRITEACL) - access |= VWRITE_ACL; - if (mask & NFSV4ACE_WRITEOWNER) - access |= VWRITE_OWNER; - if (mask & NFSV4ACE_SYNCHRONIZE) - access |= VSYNCHRONIZE; - - if (access != 0) - error = VOP_ACCESS(vp, access, cred, p); - else - error = VOP_ACCESS(vp, vflags, cred, p); - return (error); -} - -/* * Set an NFSv4 acl. */ APPLESTATIC int diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 386fb04..17714d7 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -331,8 +331,6 @@ int nfsrv_dissectace(struct nfsrv_descript *, struct acl_entry *, int *, int *, NFSPROC_T *); int nfsrv_buildacl(struct nfsrv_descript *, NFSACL_T *, enum vtype, NFSPROC_T *); -int nfsrv_aclaccess(vnode_t, accmode_t, u_int32_t, struct ucred *, - NFSPROC_T *); int nfsrv_setacl(vnode_t, NFSACL_T *, struct ucred *, NFSPROC_T *); int nfsrv_compareacl(NFSACL_T *, NFSACL_T *); @@ -514,8 +512,8 @@ int nfsvno_getattr(vnode_t, struct nfsvattr *, struct ucred *, int nfsvno_setattr(vnode_t, struct nfsvattr *, struct ucred *, NFSPROC_T *, struct nfsexstuff *); int nfsvno_getfh(vnode_t, fhandle_t *, NFSPROC_T *); -int nfsvno_accchk(vnode_t, u_int32_t, struct ucred *, - struct nfsexstuff *, NFSPROC_T *, int, int); +int nfsvno_accchk(vnode_t, accmode_t, struct ucred *, + struct nfsexstuff *, NFSPROC_T *, int, int, u_int32_t *); int nfsvno_namei(struct nfsrv_descript *, struct nameidata *, vnode_t, int, struct nfsexstuff *, NFSPROC_T *, vnode_t *); void nfsvno_setpathbuf(struct nameidata *, char **, u_long **); diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index ca80fde..3b7f8d0 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -131,32 +131,20 @@ nfsvno_getfh(struct vnode *vp, fhandle_t *fhp, struct thread *p) /* * Perform access checking for vnodes obtained from file handles that would * refer to files already opened by a Unix client. You cannot just use - * vn_writechk() and VOP_ACCESS() for two reasons. - * 1 - You must check for exported rdonly as well as MNT_RDONLY for the write case + * vn_writechk() and VOP_ACCESSX() for two reasons. + * 1 - You must check for exported rdonly as well as MNT_RDONLY for the write + * case. * 2 - The owner is to be given access irrespective of mode bits for some * operations, so that processes that chmod after opening a file don't * break. */ int -nfsvno_accchk(struct vnode *vp, u_int32_t accessbits, struct ucred *cred, - struct nfsexstuff *exp, struct thread *p, int override, int vpislocked) +nfsvno_accchk(struct vnode *vp, accmode_t accmode, struct ucred *cred, + struct nfsexstuff *exp, struct thread *p, int override, int vpislocked, + u_int32_t *supportedtypep) { struct vattr vattr; int error = 0, getret = 0; - accmode_t accmode; - - /* - * Convert accessbits to Vxxx flags. - */ - if (accessbits & (NFSV4ACE_WRITEDATA | NFSV4ACE_APPENDDATA | - NFSV4ACE_ADDFILE | NFSV4ACE_ADDSUBDIRECTORY | - NFSV4ACE_DELETECHILD | NFSV4ACE_WRITEATTRIBUTES | - NFSV4ACE_DELETE | NFSV4ACE_WRITEACL | NFSV4ACE_WRITEOWNER)) - accmode = VWRITE; - else if (accessbits & (NFSV4ACE_EXECUTE | NFSV4ACE_SEARCH)) - accmode = VEXEC; - else - accmode = VREAD; if (accmode & VWRITE) { /* Just vn_writechk() changed to check rdonly */ @@ -166,7 +154,7 @@ nfsvno_accchk(struct vnode *vp, u_int32_t accessbits, struct ucred *cred, * device resident on the file system. */ if (NFSVNO_EXRDONLY(exp) || - (vp->v_mount->mnt_flag & MNT_RDONLY)) { + (vp->v_mount->mnt_flag & MNT_RDONLY)) { switch (vp->v_type) { case VREG: case VDIR: @@ -187,22 +175,26 @@ nfsvno_accchk(struct vnode *vp, u_int32_t accessbits, struct ucred *cred, if (vpislocked == 0) NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, p); -#if defined(NFS4_ACL_EXTATTR_NAME) && defined(notyet) - /* - * This function should be called once FFS has NFSv4 ACL support - * in it. - */ /* * Should the override still be applied when ACLs are enabled? */ - if (nfsrv_useacl != 0 && NFSHASNFS4ACL(vp->v_mount)) - error = nfsrv_aclaccess(vp, accmode, accessbits, cred, p); - else -#endif - if (accessbits == NFSV4ACE_READATTRIBUTES) - error = 0; - else - error = VOP_ACCESS(vp, accmode, cred, p); + error = VOP_ACCESSX(vp, accmode, cred, p); + if (error != 0 && (accmode & (VDELETE | VDELETE_CHILD))) { + /* + * Try again with VEXPLICIT_DENY, to see if the test for + * deletion is supported. + */ + error = VOP_ACCESSX(vp, accmode | VEXPLICIT_DENY, cred, p); + if (error == 0) { + if (vp->v_type == VDIR) { + accmode &= ~(VDELETE | VDELETE_CHILD); + accmode |= VWRITE; + error = VOP_ACCESSX(vp, accmode, cred, p); + } else if (supportedtypep != NULL) { + *supportedtypep &= ~NFSACCESS_DELETE; + } + } + } /* * Allow certain operations for the owner (reads and writes @@ -790,9 +782,9 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp, else vput(ndp->ni_dvp); if (!error && nvap->na_size != VNOVAL) { - error = nfsvno_accchk(*vpp, NFSV4ACE_ADDFILE, + error = nfsvno_accchk(*vpp, VWRITE, nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE, - NFSACCCHK_VPISLOCKED); + NFSACCCHK_VPISLOCKED, NULL); if (!error) { tempsize = nvap->na_size; NFSVNO_ATTRINIT(nvap); @@ -1334,8 +1326,9 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, else NFSVNO_EXINIT(&nes); nd->nd_repstat = nfsvno_accchk(vp, - NFSV4ACE_ADDFILE, cred, &nes, p, - NFSACCCHK_NOOVERRIDE,NFSACCCHK_VPISLOCKED); + VWRITE, cred, &nes, p, + NFSACCCHK_NOOVERRIDE, + NFSACCCHK_VPISLOCKED, NULL); nd->nd_repstat = nfsrv_opencheck(clientid, stateidp, stp, vp, nd, p, nd->nd_repstat); if (!nd->nd_repstat) { @@ -1481,9 +1474,9 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram, #endif } if (!nd->nd_repstat) - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_SEARCH, + nd->nd_repstat = nfsvno_accchk(vp, VEXEC, nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE, - NFSACCCHK_VPISLOCKED); + NFSACCCHK_VPISLOCKED, NULL); if (nd->nd_repstat) { vput(vp); if (nd->nd_flag & ND_NFSV3) @@ -1752,9 +1745,9 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, if (!nd->nd_repstat && cnt == 0) nd->nd_repstat = NFSERR_TOOSMALL; if (!nd->nd_repstat) - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_SEARCH, + nd->nd_repstat = nfsvno_accchk(vp, VEXEC, nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE, - NFSACCCHK_VPISLOCKED); + NFSACCCHK_VPISLOCKED, NULL); if (nd->nd_repstat) { vput(vp); if (nd->nd_flag & ND_NFSV3) diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index c0ac41d..e56610b 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -88,6 +88,7 @@ nfsrvd_access(struct nfsrv_descript *nd, __unused int isdgram, int getret, error = 0; struct nfsvattr nva; u_int32_t testmode, nfsmode, supported = 0; + accmode_t deletebit; if (nd->nd_repstat) { nfsrv_postopattr(nd, 1, &nva); @@ -105,26 +106,30 @@ nfsrvd_access(struct nfsrv_descript *nd, __unused int isdgram, } if (nfsmode & NFSACCESS_READ) { supported |= NFSACCESS_READ; - if (nfsvno_accchk(vp, NFSV4ACE_READDATA, nd->nd_cred, exp, p, - NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED)) + if (nfsvno_accchk(vp, VREAD, nd->nd_cred, exp, p, + NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported)) nfsmode &= ~NFSACCESS_READ; } if (nfsmode & NFSACCESS_MODIFY) { supported |= NFSACCESS_MODIFY; - if (nfsvno_accchk(vp, NFSV4ACE_WRITEDATA, nd->nd_cred, exp, p, - NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED)) + if (nfsvno_accchk(vp, VWRITE, nd->nd_cred, exp, p, + NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported)) nfsmode &= ~NFSACCESS_MODIFY; } if (nfsmode & NFSACCESS_EXTEND) { supported |= NFSACCESS_EXTEND; - if (nfsvno_accchk(vp, NFSV4ACE_APPENDDATA, nd->nd_cred, exp, p, - NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED)) + if (nfsvno_accchk(vp, VWRITE | VAPPEND, nd->nd_cred, exp, p, + NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported)) nfsmode &= ~NFSACCESS_EXTEND; } if (nfsmode & NFSACCESS_DELETE) { supported |= NFSACCESS_DELETE; - if (nfsvno_accchk(vp, NFSV4ACE_DELETE, nd->nd_cred, exp, p, - NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED)) + if (vp->v_type == VDIR) + deletebit = VDELETE_CHILD; + else + deletebit = VDELETE; + if (nfsvno_accchk(vp, deletebit, nd->nd_cred, exp, p, + NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported)) nfsmode &= ~NFSACCESS_DELETE; } if (vnode_vtype(vp) == VDIR) @@ -133,8 +138,8 @@ nfsrvd_access(struct nfsrv_descript *nd, __unused int isdgram, testmode = NFSACCESS_EXECUTE; if (nfsmode & testmode) { supported |= (nfsmode & testmode); - if (nfsvno_accchk(vp, NFSV4ACE_EXECUTE, nd->nd_cred, exp, p, - NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED)) + if (nfsvno_accchk(vp, VEXEC, nd->nd_cred, exp, p, + NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED, &supported)) nfsmode &= ~testmode; } nfsmode &= supported; @@ -189,9 +194,9 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram, } if (!nd->nd_repstat) nd->nd_repstat = nfsvno_accchk(vp, - NFSV4ACE_READATTRIBUTES, - nd->nd_cred, exp, p, - NFSACCCHK_NOOVERRIDE, NFSACCCHK_VPISLOCKED); + VREAD_ATTRIBUTES, + nd->nd_cred, exp, p, NFSACCCHK_NOOVERRIDE, + NFSACCCHK_VPISLOCKED, NULL); } if (!nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); @@ -291,8 +296,9 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram, else if (nva2.na_uid != nd->nd_cred->cr_uid || NFSVNO_EXSTRICTACCESS(exp)) nd->nd_repstat = nfsvno_accchk(vp, - NFSV4ACE_WRITEDATA, nd->nd_cred, exp, p, - NFSACCCHK_NOOVERRIDE,NFSACCCHK_VPISLOCKED); + VWRITE, nd->nd_cred, exp, p, + NFSACCCHK_NOOVERRIDE, + NFSACCCHK_VPISLOCKED, NULL); } } if (!nd->nd_repstat && (nd->nd_flag & ND_NFSV4)) @@ -612,13 +618,13 @@ nfsrvd_read(struct nfsrv_descript *nd, __unused int isdgram, if (!nd->nd_repstat && (nva.na_uid != nd->nd_cred->cr_uid || NFSVNO_EXSTRICTACCESS(exp))) { - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_READDATA, + nd->nd_repstat = nfsvno_accchk(vp, VREAD, nd->nd_cred, exp, p, - NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED); + NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL); if (nd->nd_repstat) - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_EXECUTE, - nd->nd_cred, exp, p, - NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED); + nd->nd_repstat = nfsvno_accchk(vp, VEXEC, + nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER, + NFSACCCHK_VPISLOCKED, NULL); } if ((nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) nd->nd_repstat = nfsrv_lockctrl(vp, &stp, &lop, NULL, clientid, @@ -788,9 +794,9 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int isdgram, if (!nd->nd_repstat && (forat.na_uid != nd->nd_cred->cr_uid || NFSVNO_EXSTRICTACCESS(exp))) - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_WRITEDATA, + nd->nd_repstat = nfsvno_accchk(vp, VWRITE, nd->nd_cred, exp, p, - NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED); + NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL); if ((nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) { nd->nd_repstat = nfsrv_lockctrl(vp, &stp, &lop, NULL, clientid, &stateid, exp, nd, p); @@ -2146,17 +2152,17 @@ nfsrvd_lock(struct nfsrv_descript *nd, __unused int isdgram, } if (!nd->nd_repstat) { if (lflags & NFSLCK_WRITE) { - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_WRITEDATA, + nd->nd_repstat = nfsvno_accchk(vp, VWRITE, nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER, - NFSACCCHK_VPISLOCKED); + NFSACCCHK_VPISLOCKED, NULL); } else { - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_READDATA, + nd->nd_repstat = nfsvno_accchk(vp, VREAD, nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER, - NFSACCCHK_VPISLOCKED); + NFSACCCHK_VPISLOCKED, NULL); if (nd->nd_repstat) - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_EXECUTE, + nd->nd_repstat = nfsvno_accchk(vp, VEXEC, nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER, - NFSACCCHK_VPISLOCKED); + NFSACCCHK_VPISLOCKED, NULL); } } @@ -2672,15 +2678,15 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, nd->nd_repstat = NFSERR_INVAL; } if (!nd->nd_repstat && (stp->ls_flags & NFSLCK_WRITEACCESS)) - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_WRITEDATA, nd->nd_cred, - exp, p, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED); + nd->nd_repstat = nfsvno_accchk(vp, VWRITE, nd->nd_cred, + exp, p, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL); if (!nd->nd_repstat && (stp->ls_flags & NFSLCK_READACCESS)) { - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_READDATA, nd->nd_cred, - exp, p, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED); + nd->nd_repstat = nfsvno_accchk(vp, VREAD, nd->nd_cred, + exp, p, NFSACCCHK_ALLOWOWNER, NFSACCCHK_VPISLOCKED, NULL); if (nd->nd_repstat) - nd->nd_repstat = nfsvno_accchk(vp, NFSV4ACE_EXECUTE, + nd->nd_repstat = nfsvno_accchk(vp, VEXEC, nd->nd_cred, exp, p, NFSACCCHK_ALLOWOWNER, - NFSACCCHK_VPISLOCKED); + NFSACCCHK_VPISLOCKED, NULL); } if (!nd->nd_repstat) { -- cgit v1.1