summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2009-12-25 20:44:19 +0000
committerrmacklem <rmacklem@FreeBSD.org>2009-12-25 20:44:19 +0000
commit0ccdae7b7da6e583cf244fbb3adddf920a68584b (patch)
tree93356183bb5da1c7bab0662924509ad7da2e215e /sys/fs
parent545cc5fec7115d450d5b76c2f598d1eafb16d592 (diff)
downloadFreeBSD-src-0ccdae7b7da6e583cf244fbb3adddf920a68584b.zip
FreeBSD-src-0ccdae7b7da6e583cf244fbb3adddf920a68584b.tar.gz
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
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/nfs/nfs_commonacl.c64
-rw-r--r--sys/fs/nfs/nfs_var.h6
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c73
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c74
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) {
OpenPOWER on IntegriCloud