aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/fs/nfs/nfs_var.h15
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c84
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c86
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsubs.c38
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)
@@ -7391,6 +7437,20 @@ nfsrv_checknospc(void)
}
/*
+ * 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.
*/
static void
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: