diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 6b14c8486272..49a94323a572 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -409,7 +409,7 @@ void nfsv4_gidtostr(gid_t, u_char **, int *); int nfsv4_strtogid(struct nfsrv_descript *, u_char *, int, gid_t *); int nfsrv_checkuidgid(struct nfsrv_descript *, struct nfsvattr *); void nfsrv_fixattr(struct nfsrv_descript *, vnode_t, - struct nfsvattr *, NFSACL_T *, NFSPROC_T *, nfsattrbit_t *, + struct nfsvattr *, NFSACL_T *, NFSACL_T *, NFSPROC_T *, nfsattrbit_t *, struct nfsexstuff *); int nfsrv_errmoved(int); int nfsrv_putreferralattr(struct nfsrv_descript *, nfsattrbit_t *, @@ -734,7 +734,7 @@ int nfsvno_statfs(vnode_t, struct statfs *); void nfsvno_getfs(struct nfsfsinfo *, int); void nfsvno_open(struct nfsrv_descript *, struct nameidata *, nfsquad_t, nfsv4stateid_t *, struct nfsstate *, int *, struct nfsvattr *, int32_t *, - int, NFSACL_T *, nfsattrbit_t *, struct ucred *, bool, + int, NFSACL_T *, NFSACL_T *, nfsattrbit_t *, struct ucred *, bool, struct nfsexstuff *, vnode_t *); int nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct nfsrv_descript *, NFSPROC_T *); @@ -742,10 +742,10 @@ int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *, struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, bool, bool, bool, uint32_t, bool); -int nfsrv_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *, - NFSACL_T *, NFSPROC_T *); -int nfsv4_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *, - NFSACL_T *, NFSPROC_T *); +int nfsrv_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, + nfsattrbit_t *, NFSACL_T *, NFSACL_T *, NFSPROC_T *); +int nfsv4_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, + nfsattrbit_t *, NFSACL_T *, NFSACL_T *, NFSPROC_T *); int nfsvno_checkexp(mount_t, NFSSOCKADDR_T, struct nfsexstuff *, struct ucred **); int nfsvno_fhtovp(mount_t, fhandle_t *, NFSSOCKADDR_T, int, @@ -767,7 +767,8 @@ int nfsrv_dscreate(struct vnode *, struct vattr *, struct vattr *, struct ucred *, NFSPROC_T *, struct vnode **); int nfsrv_updatemdsattr(struct vnode *, struct nfsvattr *, NFSPROC_T *); void nfsrv_killrpcs(struct nfsmount *); -int nfsrv_setacl(struct vnode *, NFSACL_T *, struct ucred *, NFSPROC_T *); +int nfsrv_setacl(struct vnode *, + NFSACL_T *, acl_type_t, struct ucred *, NFSPROC_T *); int nfsvno_seek(struct nfsrv_descript *, struct vnode *, u_long, off_t *, int, bool *, struct ucred *, NFSPROC_T *); int nfsvno_allocate(struct vnode *, off_t, off_t, struct ucred *, NFSPROC_T *); diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 841ec2315f1c..ec2c15485601 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -1457,7 +1457,7 @@ nfsvno_getsymlink(struct nfsrv_descript *nd, struct nfsvattr *nvap, *pathcpp = NULL; *lenp = 0; if ((nd->nd_flag & ND_NFSV3) && - (error = nfsrv_sattr(nd, NULL, nvap, NULL, NULL, p))) + (error = nfsrv_sattr(nd, NULL, nvap, NULL, NULL, NULL, p))) goto nfsmout; NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); len = fxdr_unsigned(int, *tl); @@ -1969,8 +1969,8 @@ void nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, nfsquad_t clientid, nfsv4stateid_t *stateidp, struct nfsstate *stp, int *exclusive_flagp, struct nfsvattr *nvap, int32_t *cverf, int create, - NFSACL_T *aclp, nfsattrbit_t *attrbitp, struct ucred *cred, bool done_namei, - struct nfsexstuff *exp, struct vnode **vpp) + NFSACL_T *aclp, NFSACL_T *daclp, nfsattrbit_t *attrbitp, struct ucred *cred, + bool done_namei, struct nfsexstuff *exp, struct vnode **vpp) { struct vnode *vp = NULL; u_quad_t tempsize; @@ -2023,7 +2023,7 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp, NFSATTRBIT_TIMEACCESS); } else { nfsrv_fixattr(nd, ndp->ni_vp, nvap, - aclp, p, attrbitp, exp); + aclp, daclp, p, attrbitp, exp); } } vp = ndp->ni_vp; @@ -2953,7 +2953,7 @@ ateof: clone_blksize = 0; if (nvp != NULL) { supports_nfsv4acls = - nfs_supportsnfsv4acls(nvp); + nfs_supportsacls(nvp); if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_XATTRSUPPORT)) { ret = VOP_GETEXTATTR(nvp, @@ -3075,7 +3075,7 @@ nfsmout: */ int nfsrv_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap, - nfsattrbit_t *attrbitp, NFSACL_T *aclp, struct thread *p) + nfsattrbit_t *attrbitp, NFSACL_T *aclp, NFSACL_T *daclp, struct thread *p) { u_int32_t *tl; struct nfsv2_sattr *sp; @@ -3156,7 +3156,7 @@ nfsrv_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap, } break; case ND_NFSV4: - error = nfsv4_sattr(nd, vp, nvap, attrbitp, aclp, p); + error = nfsv4_sattr(nd, vp, nvap, attrbitp, aclp, daclp, p); } nfsmout: NFSEXITCODE2(error, nd); @@ -3169,7 +3169,7 @@ nfsmout: */ int nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap, - nfsattrbit_t *attrbitp, NFSACL_T *aclp, struct thread *p) + nfsattrbit_t *attrbitp, NFSACL_T *aclp, NFSACL_T *daclp, struct thread *p) { u_int32_t *tl; int attrsum = 0; @@ -3203,6 +3203,10 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap, NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_HIDDEN) || NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SYSTEM)) nvap->na_flags = 0; + if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_ACL) && + (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_POSIXDEFAULTACL) || + NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_POSIXACCESSACL))) + nd->nd_repstat = NFSERR_INVAL; } moderet = 0; for (; bitpos < NFSATTRBIT_MAX; bitpos++) { @@ -3416,6 +3420,38 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap, } attrsum += 2 * NFSX_UNSIGNED; break; + case NFSATTRBIT_POSIXACCESSACL: + error = nfsrv_dissectacl(nd, aclp, true, &aceerr, + &aclsize, p); + if (error != 0) + goto nfsmout; + if (!nd->nd_repstat) { + if ((nd->nd_flag & ND_NFSV42) == 0) + nd->nd_repstat = NFSERR_ATTRNOTSUPP; + else if (aclp != NULL && aclp->acl_cnt == 0) + nd->nd_repstat = NFSERR_INVAL; + else if (aceerr != 0) + nd->nd_repstat = aceerr; + } + attrsum += aclsize; + break; + case NFSATTRBIT_POSIXDEFAULTACL: + error = nfsrv_dissectacl(nd, daclp, true, &aceerr, + &aclsize, p); + if (error != 0) + goto nfsmout; + if (!nd->nd_repstat) { + if ((nd->nd_flag & ND_NFSV42) == 0) + nd->nd_repstat = NFSERR_ATTRNOTSUPP; + else if (aclp != NULL && aclp->acl_cnt == 0) + nd->nd_repstat = NFSERR_INVAL; + else if (aceerr != 0) + nd->nd_repstat = aceerr; + else if (vp != NULL && vp->v_type != VDIR) + nd->nd_repstat = NFSERR_INVAL; + } + attrsum += aclsize; + break; default: nd->nd_repstat = NFSERR_ATTRNOTSUPP; /* @@ -6824,14 +6860,17 @@ nfsrv_pnfsstatfs(struct statfs *sf, struct mount *mp) } /* - * Set an NFSv4 acl. + * Set an acl. */ int -nfsrv_setacl(struct vnode *vp, NFSACL_T *aclp, struct ucred *cred, NFSPROC_T *p) +nfsrv_setacl(struct vnode *vp, NFSACL_T *aclp, acl_type_t atype, + struct ucred *cred, NFSPROC_T *p) { int error; - if (nfsrv_useacl == 0 || nfs_supportsnfsv4acls(vp) == 0) { + if (nfsrv_useacl == 0 || (atype == ACL_TYPE_NFS4 && + nfs_supportsnfsv4acls(vp) == 0) || (atype != ACL_TYPE_NFS4 && + nfs_supportsposixacls(vp) == 0)) { error = NFSERR_ATTRNOTSUPP; goto out; } @@ -6845,7 +6884,14 @@ nfsrv_setacl(struct vnode *vp, NFSACL_T *aclp, struct ucred *cred, NFSPROC_T *p) error = NFSERR_ATTRNOTSUPP; goto out; } - error = VOP_SETACL(vp, ACL_TYPE_NFS4, aclp, cred, p); + if (aclp->acl_cnt == 0) { + if (atype != ACL_TYPE_DEFAULT || vp->v_type != VDIR) { + error = NFSERR_INVAL; + goto out; + } + error = VOP_SETACL(vp, atype, NULL, cred, p); + } else + error = VOP_SETACL(vp, atype, aclp, cred, p); if (error == 0) { error = nfsrv_dssetacl(vp, aclp, cred, p); if (error == ENOENT) @@ -7379,6 +7425,20 @@ nfsrv_checknospc(void) free(devid, M_TEMP); } +/* + * Return the correct ACL support value for a vnode. + */ +int +nfs_supportsacls(struct vnode *vp) +{ + + if (nfs_supportsnfsv4acls(vp) != 0) + return (SUPPACL_NFSV4); + else if (nfs_supportsposixacls(vp) != 0) + return (SUPPACL_POSIX); + return (SUPPACL_NONE); +} + /* * Initialize everything that needs to be initialized for a vnet. */ diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 394b63c2ab07..a296082f31d3 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -122,7 +122,7 @@ static void nfsrvd_symlinksub(struct nfsrv_descript *nd, struct nameidata *ndp, static void nfsrvd_mkdirsub(struct nfsrv_descript *nd, struct nameidata *ndp, struct nfsvattr *nvap, fhandle_t *fhp, vnode_t *vpp, vnode_t dirp, struct nfsvattr *dirforp, struct nfsvattr *diraftp, - int *diraft_retp, nfsattrbit_t *attrbitp, NFSACL_T *aclp, + int *diraft_retp, nfsattrbit_t *attrbitp, NFSACL_T *aclp, NFSACL_T *daclp, NFSPROC_T *p, struct nfsexstuff *exp); /* @@ -310,7 +310,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram, nd->nd_repstat = nfsrv_checkgetattr(nd, vp, &nva, &attrbits, p); if (nd->nd_repstat == 0) { - supports_nfsv4acls = nfs_supportsnfsv4acls(vp); + supports_nfsv4acls = nfs_supportsacls(vp); xattrsupp = false; if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_XATTRSUPPORT)) { @@ -409,7 +409,7 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram, struct timespec guard = { 0, 0 }; nfsattrbit_t attrbits, retbits; nfsv4stateid_t stateid; - NFSACL_T *aclp = NULL; + NFSACL_T *aclp = NULL, *daclp = NULL; struct thread *p = curthread; NFSZERO_ATTRBIT(&retbits); @@ -420,6 +420,8 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram, #ifdef NFS4_ACL_EXTATTR_NAME aclp = acl_alloc(M_WAITOK); aclp->acl_cnt = 0; + daclp = acl_alloc(M_WAITOK); + daclp->acl_cnt = 0; #endif gotproxystateid = 0; NFSVNO_ATTRINIT(&nva); @@ -435,7 +437,7 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram, stateid.seqid == 0xffffffff) gotproxystateid = 1; } - error = nfsrv_sattr(nd, vp, &nva, &attrbits, aclp, p); + error = nfsrv_sattr(nd, vp, &nva, &attrbits, aclp, daclp, p); if (error) goto nfsmout; @@ -464,6 +466,7 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram, vput(vp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif nfsrv_wcc(nd, preat_ret, &nva2, postat_ret, &nva); goto out; @@ -613,10 +616,28 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram, #ifdef NFS4_ACL_EXTATTR_NAME if (!nd->nd_repstat && aclp->acl_cnt > 0 && NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_ACL)) { - nd->nd_repstat = nfsrv_setacl(vp, aclp, nd->nd_cred, p); - if (!nd->nd_repstat) + nd->nd_repstat = nfsrv_setacl(vp, aclp, ACL_TYPE_NFS4, + nd->nd_cred, p); + if (!nd->nd_repstat) NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_ACL); } + if (!nd->nd_repstat && aclp->acl_cnt > 0 && + NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_POSIXACCESSACL)) { + nd->nd_repstat = nfsrv_setacl(vp, aclp, ACL_TYPE_ACCESS, + nd->nd_cred, p); + if (!nd->nd_repstat) + NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_POSIXACCESSACL); + } + if (!nd->nd_repstat && + NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_POSIXDEFAULTACL)) { + if (daclp == NULL) + nd->nd_repstat = NFSERR_INVAL; + if (nd->nd_repstat == 0) + nd->nd_repstat = nfsrv_setacl(vp, daclp, + ACL_TYPE_DEFAULT, nd->nd_cred, p); + if (nd->nd_repstat == 0) + NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_POSIXDEFAULTACL); + } #endif } else if (!nd->nd_repstat) { nd->nd_repstat = nfsvno_setattr(vp, &nva, nd->nd_cred, p, @@ -630,6 +651,7 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram, vput(vp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif if (nd->nd_flag & ND_NFSV3) nfsrv_wcc(nd, preat_ret, &nva2, postat_ret, &nva); @@ -645,6 +667,7 @@ nfsmout: vput(vp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif if (nd->nd_flag & ND_NFSV4) { /* @@ -1290,7 +1313,8 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram, switch (how) { case NFSCREATE_GUARDED: case NFSCREATE_UNCHECKED: - error = nfsrv_sattr(nd, NULL, &nva, NULL, NULL, p); + error = nfsrv_sattr(nd, NULL, &nva, NULL, NULL, + NULL, p); if (error) goto nfsmout; break; @@ -1415,7 +1439,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, nfsattrbit_t attrbits; char *bufp = NULL, *pathcp = NULL; u_long *hashp, cnflags; - NFSACL_T *aclp = NULL; + NFSACL_T *aclp = NULL, *daclp = NULL; struct thread *p = curthread; NFSVNO_ATTRINIT(&nva); @@ -1427,6 +1451,8 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, #ifdef NFS4_ACL_EXTATTR_NAME aclp = acl_alloc(M_WAITOK); aclp->acl_cnt = 0; + daclp = acl_alloc(M_WAITOK); + daclp->acl_cnt = 0; #endif /* @@ -1473,6 +1499,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, vrele(dp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif goto out; } @@ -1487,7 +1514,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); vtyp = nfsv34tov_type(*tl); } - error = nfsrv_sattr(nd, NULL, &nva, &attrbits, aclp, p); + error = nfsrv_sattr(nd, NULL, &nva, &attrbits, aclp, daclp, p); if (error) goto nfsmout; nva.na_type = vtyp; @@ -1511,6 +1538,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, vrele(dp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif nfsvno_relpathbuf(&named); if (pathcp) @@ -1544,6 +1572,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, } #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif if (nd->nd_flag & ND_NFSV3) nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, @@ -1556,10 +1585,11 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, if ((nd->nd_flag & ND_NFSV4) && (vtyp == VDIR || vtyp == VLNK)) { if (vtyp == VDIR) { nfsrvd_mkdirsub(nd, &named, &nva, fhp, vpp, dirp, - &dirfor, &diraft, &diraft_ret, &attrbits, aclp, p, - exp); + &dirfor, &diraft, &diraft_ret, &attrbits, aclp, + daclp, p, exp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif goto out; } else if (vtyp == VLNK) { @@ -1568,6 +1598,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, aclp, p, exp, pathcp, pathlen); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif free(pathcp, M_TEMP); goto out; @@ -1577,7 +1608,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, nd->nd_repstat = nfsvno_mknod(&named, &nva, nd->nd_cred, p); if (!nd->nd_repstat) { vp = named.ni_vp; - nfsrv_fixattr(nd, vp, &nva, aclp, p, &attrbits, exp); + nfsrv_fixattr(nd, vp, &nva, aclp, daclp, p, &attrbits, exp); nd->nd_repstat = nfsvno_getfh(vp, fhp, p); if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, @@ -1608,6 +1639,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram, nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif out: @@ -1617,6 +1649,7 @@ nfsmout: vrele(dp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif if (bufp) nfsvno_relpathbuf(&named); @@ -2086,7 +2119,8 @@ nfsrvd_symlinksub(struct nfsrv_descript *nd, struct nameidata *ndp, nd->nd_repstat = nfsvno_symlink(ndp, nvap, pathcp, pathlen, !(nd->nd_flag & ND_NFSV2), nd->nd_saveduid, nd->nd_cred, p, exp); if (!nd->nd_repstat && !(nd->nd_flag & ND_NFSV2)) { - nfsrv_fixattr(nd, ndp->ni_vp, nvap, aclp, p, attrbitp, exp); + nfsrv_fixattr(nd, ndp->ni_vp, nvap, aclp, NULL, p, attrbitp, + exp); if (nd->nd_flag & ND_NFSV3) { nd->nd_repstat = nfsvno_getfh(ndp->ni_vp, fhp, p); if (!nd->nd_repstat) @@ -2143,7 +2177,8 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int isdgram, if (!nd->nd_repstat) { NFSVNO_ATTRINIT(&nva); if (nd->nd_flag & ND_NFSV3) { - error = nfsrv_sattr(nd, NULL, &nva, NULL, NULL, p); + error = nfsrv_sattr(nd, NULL, &nva, NULL, NULL, NULL, + p); if (error) goto nfsmout; } else { @@ -2179,7 +2214,7 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int isdgram, * Call nfsrvd_mkdirsub() for the code common to V4 as well. */ nfsrvd_mkdirsub(nd, &named, &nva, fhp, vpp, dirp, &dirfor, &diraft, - &diraft_ret, NULL, NULL, p, exp); + &diraft_ret, NULL, NULL, NULL, p, exp); if (nd->nd_flag & ND_NFSV3) { if (!nd->nd_repstat) { @@ -2209,7 +2244,7 @@ static void nfsrvd_mkdirsub(struct nfsrv_descript *nd, struct nameidata *ndp, struct nfsvattr *nvap, fhandle_t *fhp, vnode_t *vpp, vnode_t dirp, struct nfsvattr *dirforp, struct nfsvattr *diraftp, - int *diraft_retp, nfsattrbit_t *attrbitp, NFSACL_T *aclp, + int *diraft_retp, nfsattrbit_t *attrbitp, NFSACL_T *aclp, NFSACL_T *daclp, NFSPROC_T *p, struct nfsexstuff *exp) { vnode_t vp; @@ -2220,7 +2255,7 @@ nfsrvd_mkdirsub(struct nfsrv_descript *nd, struct nameidata *ndp, nd->nd_cred, p, exp); if (!nd->nd_repstat) { vp = ndp->ni_vp; - nfsrv_fixattr(nd, vp, nvap, aclp, p, attrbitp, exp); + nfsrv_fixattr(nd, vp, nvap, aclp, daclp, p, attrbitp, exp); nd->nd_repstat = nfsvno_getfh(vp, fhp, p); if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat) nd->nd_repstat = nfsvno_getattr(vp, nvap, nd, p, 1, @@ -2941,7 +2976,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, nfsquad_t clientid; char *bufp = NULL; u_long *hashp; - NFSACL_T *aclp = NULL; + NFSACL_T *aclp = NULL, *daclp = NULL; struct thread *p = curthread; bool done_namei; __enum_uint8_decl(wdelegace) { USENONE, USEMODE, USENFSV4ACL } @@ -2950,6 +2985,8 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, #ifdef NFS4_ACL_EXTATTR_NAME aclp = acl_alloc(M_WAITOK); aclp->acl_cnt = 0; + daclp = acl_alloc(M_WAITOK); + daclp->acl_cnt = 0; #endif NFSZERO_ATTRBIT(&attrbits); done_namei = false; @@ -3060,7 +3097,8 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, switch (how) { case NFSCREATE_UNCHECKED: case NFSCREATE_GUARDED: - error = nfsv4_sattr(nd, NULL, &nva, &attrbits, aclp, p); + error = nfsv4_sattr(nd, NULL, &nva, &attrbits, aclp, + daclp, p); if (error) goto nfsmout; /* @@ -3086,7 +3124,8 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF); cverf[0] = *tl++; cverf[1] = *tl; - error = nfsv4_sattr(nd, NULL, &nva, &attrbits, aclp, p); + error = nfsv4_sattr(nd, NULL, &nva, &attrbits, aclp, + daclp, p); if (error != 0) goto nfsmout; if ((vn_irflag_read(dp) & VIRF_NAMEDDIR) != 0 || @@ -3153,6 +3192,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, vrele(dp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif free(stp, M_NFSDSTATE); nfsvno_relpathbuf(&named); @@ -3209,8 +3249,8 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, } } nfsvno_open(nd, &named, clientid, &stateid, stp, - &exclusive_flag, &nva, cverf, create, aclp, &attrbits, - nd->nd_cred, done_namei, exp, &vp); + &exclusive_flag, &nva, cverf, create, aclp, daclp, + &attrbits, nd->nd_cred, done_namei, exp, &vp); } else if (claim == NFSV4OPEN_CLAIMPREVIOUS || claim == NFSV4OPEN_CLAIMFH || claim == NFSV4OPEN_CLAIMDELEGATECURFH || claim == NFSV4OPEN_CLAIMDELEGATEPREVFH) { @@ -3465,6 +3505,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, vrele(dirp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif NFSEXITCODE2(0, nd); return (0); @@ -3472,6 +3513,7 @@ nfsmout: vrele(dp); #ifdef NFS4_ACL_EXTATTR_NAME acl_free(aclp); + acl_free(daclp); #endif if (stp) free(stp, M_NFSDSTATE); diff --git a/sys/fs/nfsserver/nfs_nfsdsubs.c b/sys/fs/nfsserver/nfs_nfsdsubs.c index b09ec1b3a062..ea8382e4282a 100644 --- a/sys/fs/nfsserver/nfs_nfsdsubs.c +++ b/sys/fs/nfsserver/nfs_nfsdsubs.c @@ -1644,8 +1644,8 @@ out: */ void nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp, - struct nfsvattr *nvap, NFSACL_T *aclp, NFSPROC_T *p, nfsattrbit_t *attrbitp, - struct nfsexstuff *exp) + struct nfsvattr *nvap, NFSACL_T *aclp, NFSACL_T *daclp, NFSPROC_T *p, + nfsattrbit_t *attrbitp, struct nfsexstuff *exp) { int change = 0; struct nfsvattr nva; @@ -1709,16 +1709,34 @@ nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp, } #ifdef NFS4_ACL_EXTATTR_NAME if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_ACL) && - nfsrv_useacl != 0 && aclp != NULL) { - if (aclp->acl_cnt > 0) { - error = nfsrv_setacl(vp, aclp, nd->nd_cred, p); - if (error) { - NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_ACL); - } - } + nfsrv_useacl != 0 && aclp != NULL && aclp->acl_cnt > 0) { + error = nfsrv_setacl(vp, aclp, ACL_TYPE_NFS4, + nd->nd_cred, p); + if (error != 0) + NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_ACL); } else -#endif + NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_ACL); + if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_POSIXACCESSACL) && + nfsrv_useacl != 0 && aclp != NULL && aclp->acl_cnt > 0) { + error = nfsrv_setacl(vp, aclp, ACL_TYPE_ACCESS, + nd->nd_cred, p); + if (error != 0) + NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_POSIXACCESSACL); + } else + NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_POSIXACCESSACL); + if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_POSIXDEFAULTACL) && + nfsrv_useacl != 0 && daclp != NULL && daclp->acl_cnt > 0) { + error = nfsrv_setacl(vp, daclp, ACL_TYPE_DEFAULT, + nd->nd_cred, p); + if (error != 0) + NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_POSIXDEFAULTACL); + } else + NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_POSIXDEFAULTACL); +#else NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_ACL); + NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_POSIXACCESSACL); + NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_POSIXDEFAULTACL); +#endif nd->nd_cred->cr_uid = tuid; out: