The branch main has been updated by rmacklem:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=8e3fd450cc53d37fcf4e7f460f559d03c22c0d84

commit 8e3fd450cc53d37fcf4e7f460f559d03c22c0d84
Author:     Rick Macklem <[email protected]>
AuthorDate: 2025-12-22 00:04:24 +0000
Commit:     Rick Macklem <[email protected]>
CommitDate: 2025-12-22 00:08: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.
    
    Fixes:  a35bbd5d9f5f ("nfscommon: Add some support for POSIX draft ACLs")
---
 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 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:

Reply via email to