f (NFSVOPLOCK(vp, LK_SHARED) == 0) { + error = VOP_ACCESSX(vp, VREAD_ACL, cred, p); + if (error == 0) + error = VOP_GETACL(vp, ACL_TYPE_ACCESS, + npaclp, cred, p); + NFSVOPUNLOCK(vp); + } else + error = NFSERR_PERM; + if (error != 0) { + if (reterr) { + nd->nd_repstat = NFSERR_INVAL; + free(fs, M_STATFS); + return (0); + } + NFSCLRBIT_ATTRBIT(retbitp, + NFSATTRBIT_POSIXACCESSACL); + } + } + } + if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_POSIXDEFAULTACL)) { + if (nfsrv_useacl == 0 || ((cred != NULL || p != NULL) && + supports_nfsv4acls != SUPPACL_POSIX)) { + NFSCLRBIT_ATTRBIT(retbitp, NFSATTRBIT_POSIXDEFAULTACL); + } else if (ndaclp != NULL) { + if (NFSVOPLOCK(vp, LK_SHARED) == 0) { + error = VOP_ACCESSX(vp, VREAD_ACL, cred, p); + if (error == 0) + error = VOP_GETACL(vp, ACL_TYPE_DEFAULT, + ndaclp, cred, p); + NFSVOPUNLOCK(vp); + } else + error = NFSERR_PERM; + if (error != 0) + ndaclp->acl_cnt = 0; + } + } + /* * Put out the attribute bitmap for the ones being filled in * and get the field for the number of attributes returned. @@ -2813,10 +2993,17 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, case NFSATTRBIT_SUPPORTEDATTRS: NFSSETSUPP_ATTRBIT(&attrbits, nd); if (nfsrv_useacl == 0 || ((cred != NULL || p != NULL) - && supports_nfsv4acls == 0)) { + && supports_nfsv4acls != SUPPACL_NFSV4)) { NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACLSUPPORT); NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACL); } + if (nfsrv_useacl == 0 || ((cred != NULL || p != NULL) + && supports_nfsv4acls != SUPPACL_POSIX)) { + NFSCLRBIT_ATTRBIT(&attrbits, + NFSATTRBIT_POSIXACCESSACL); + NFSCLRBIT_ATTRBIT(&attrbits, + NFSATTRBIT_POSIXDEFAULTACL); + } if (!has_hiddensystem) { NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN); NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM); @@ -3321,6 +3508,24 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, *tl = txdr_unsigned(clone_blksize); retnum += NFSX_UNSIGNED; break; + case NFSATTRBIT_ACLTRUEFORM: + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(nfs_trueform(vp)); + retnum += NFSX_UNSIGNED; + break; + case NFSATTRBIT_ACLTRUEFORMSCOPE: + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4_ACL_SCOPE_FILE_SYSTEM); + retnum += NFSX_UNSIGNED; + break; + case NFSATTRBIT_POSIXACCESSACL: + retnum += nfsrv_buildposixacl(nd, paclp, + ACL_TYPE_ACCESS); + break; + case NFSATTRBIT_POSIXDEFAULTACL: + retnum += nfsrv_buildposixacl(nd, daclp, + ACL_TYPE_DEFAULT); + break; default: printf("EEK! Bad V4 attribute bitpos=%d\n", bitpos); } @@ -3328,6 +3533,10 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, } if (naclp != NULL) acl_free(naclp); + if (npaclp != NULL) + acl_free(npaclp); + if (ndaclp != NULL) + acl_free(ndaclp); free(fs, M_STATFS); *retnump = txdr_unsigned(retnum); return (retnum + prefixnum); @@ -5346,6 +5555,23 @@ nfsrpc_destroysession(struct nfsmount *nmp, struct nfsclsession *tsep, return (error); } +/* + * Determine the true form (the type of ACL stored on the file) for the + * vnode argument. + */ +static uint32_t +nfs_trueform(struct vnode *vp) +{ + uint32_t trueform; + + trueform = NFSV4_ACL_MODEL_NONE; + if ((vp->v_mount->mnt_flag & MNT_NFS4ACLS) != 0) + trueform = NFSV4_ACL_MODEL_NFS4; + else if ((vp->v_mount->mnt_flag & MNT_ACLS) != 0) + trueform = NFSV4_ACL_MODEL_POSIX_DRAFT; + return (trueform); +} + /* * Translate a vnode type into an NFSv4 type, including the named * attribute types. diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 49a94323a572..c04c3951d42d 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -443,8 +443,11 @@ int nfs_supportsposixacls(struct vnode *); int nfsrv_dissectace(struct nfsrv_descript *, struct acl_entry *, bool, int *, int *, NFSPROC_T *); uint32_t nfs_aceperm(acl_perm_t); +int nfsrv_dissectposixace(struct nfsrv_descript *, struct acl_entry *, + bool, int *, int *); int nfsrv_buildacl(struct nfsrv_descript *, NFSACL_T *, __enum_uint8(vtype), NFSPROC_T *); +int nfsrv_buildposixacl(struct nfsrv_descript *, NFSACL_T *, acl_type_t); int nfsrv_compareacl(NFSACL_T *, NFSACL_T *); /* nfs_clrpcops.c */