From nobody Thu Feb 5 01:24:49 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4f5zzP4nKCz6Qxl8 for ; Thu, 05 Feb 2026 01:24:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4f5zzP4J7hz3cR7 for ; Thu, 05 Feb 2026 01:24:49 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1770254689; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=brYvB6dzKguVEuNWWiC6TvU+DiFnIA9dY7n7dhCGLP8=; b=XwBoRQIbdp9mnX2zCrnUnazVW+vj3bDA5IbnyVFTD59Le/G8UmbOLe7U+Y2ttfX1BWe6pn VwW0Kf5l5g9SPgAzWgpB1aQbt2a1W0nfdL8YHVHrQp7jXz/eZ7vtb9jOt6xttYeulIFfsQ 4uE0DDDIE/ZDJZhsPhucevztz4qJK1uHESyt7+rXMcmpyIklkk8gGCOkmpSgX80LPlAUKq ebmQFHcVV8qZvLJtfyvix4YfrmDytQkckpUMh8wVm/r1eR/YdfLiW+g/IJKp5f/gzlvnm7 gMSzSBzuMdOeZ/XCKVet1zH65gM14XjUDObMu82rKbYjUVvPOCe7hlRm7CwCCg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1770254689; a=rsa-sha256; cv=none; b=x7GSX/0Ww5wKzgIq9vrNXIpgDGwHqI7N5KdnadnNcxn+G+cZCHrnXYOfsuQTkw+RBBDeGX G6pzvKwlHaP2ltEp/MvQw/imN/yoIP88WFR2J6nvuwXn30ItOM+OlG2fiGTVc7kOrCEmL5 ap9OjxTCcItmeen91CFw+V0G//G0bwOBrW26UfXTrqpMOeHnulag0RzfLTviqPjgIdqNEC 7c+fG1V5gWM11B9NnYyVh331yvrguLnUPl6Ap7rx9OYRriV3P/GRNC6o+4lTN1pbWz0Low Z/PD4Y7Mg4b/iHzZ+CTJPCf7L+XuwoJp8YhLfqUTcbKqdecAle4c/mON70FCPg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1770254689; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=brYvB6dzKguVEuNWWiC6TvU+DiFnIA9dY7n7dhCGLP8=; b=lTvn8Ujs5ZWbs6RMfXQaodaKfIiJzFp8xkcZ8qy6DRzkjFvVuU8OGIZGckXer5Qii35FyI 9zMokEAUFP3qoynUW5yU7ltqNek8S/nIsjmjFGpOITHPQZhp1JichbrnocnjpSSdnwFDZK lHkFpZ2Yxj1juV5oiPGaammj38zlaZ8iBu3KmYEID+i0zg0JafPHfmlA9g8QKDIkXkN8nG KmxMCLZsurXuGyI+fYBPWIngQZQTwf5wHzPYSVulmX43C+fggKS0orz2JEasnZHgoCvx4U 9evRDAOBLEzxrVZibPZ7P8+/JSJY7z4ZnjbeZ+t35ACehO5IOUr7TpKaFhSNyg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4f5zzP3f4yz1MTl for ; Thu, 05 Feb 2026 01:24:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3857e by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 05 Feb 2026 01:24:49 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Rick Macklem Subject: git: 20bfa56c514b - stable/15 - nfsd: Add some support for POSIX draft ACLs List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 20bfa56c514b8bbbae1e4d4be63ace0a68add412 Auto-Submitted: auto-generated Date: Thu, 05 Feb 2026 01:24:49 +0000 Message-Id: <6983f161.3857e.26572f67@gitrepo.freebsd.org> The branch stable/15 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=20bfa56c514b8bbbae1e4d4be63ace0a68add412 commit 20bfa56c514b8bbbae1e4d4be63ace0a68add412 Author: Rick Macklem AuthorDate: 2025-12-22 00:04:24 +0000 Commit: Rick Macklem CommitDate: 2026-02-05 01:23:05 +0000 nfsd: Add some support for POSIX draft ACLs An internet draft (expected to become an RFC someday) https://datatracker.ietf.org/doc/draft-ietf-nfsv4-posix-acls describes an extension to NFSv4.2 to handle POSIX draft ACLs. This is the second of several patches that implement the above draft. The only semantics change would be if you have exported a UFS file system mounted with the "acl" option. In that case, you would see the acl attribute supported. This is bogus, but will be handled in the next commit. (cherry picked from commit 8e3fd450cc53d37fcf4e7f460f559d03c22c0d84) --- sys/fs/nfs/nfs_var.h | 15 +++---- sys/fs/nfsserver/nfs_nfsdport.c | 84 ++++++++++++++++++++++++++++++++++------ sys/fs/nfsserver/nfs_nfsdserv.c | 86 ++++++++++++++++++++++++++++++----------- sys/fs/nfsserver/nfs_nfsdsubs.c | 38 +++++++++++++----- 4 files changed, 172 insertions(+), 51 deletions(-) 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 18e5813596c6..61d0f2aa8f90 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; @@ -2034,7 +2034,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; @@ -2964,7 +2964,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, @@ -3086,7 +3086,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; @@ -3167,7 +3167,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); @@ -3180,7 +3180,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; @@ -3214,6 +3214,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++) { @@ -3427,6 +3431,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; /* @@ -6835,14 +6871,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; } @@ -6856,7 +6895,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) @@ -7390,6 +7436,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 71b32082a91e..faccb174d998 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 cc0e169af9b7..c8c78d98be72 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; @@ -1747,16 +1747,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: