Skip to content

Commit

Permalink
Restore macOS ACL support
Browse files Browse the repository at this point in the history
Some of the ACL hoops were missed out of the new port.

Signed-off-by: Jorgen Lundman <lundman@lundman.net>
  • Loading branch information
lundman committed Feb 19, 2023
1 parent bfe7c5a commit d37bb30
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 31 deletions.
30 changes: 18 additions & 12 deletions module/os/macos/zfs/zfs_acl.c
Expand Up @@ -856,9 +856,12 @@ zfs_mode_compute(uint64_t fmode, zfs_acl_t *aclp,
* HFS: -rw-r--r--+ 1 root wheel 0 Nov 12 12:39 file.txt
* 0: user:root allow execute
*/

#ifdef __APPLE__
if (entry_type == ACE_OWNER) {
#else
if (entry_type == ACE_OWNER || (entry_type == 0 &&
who == fuid)) {
#endif
if ((access_mask & ACE_READ_DATA) &&
(!(seen & S_IRUSR))) {
seen |= S_IRUSR;
Expand All @@ -880,8 +883,12 @@ zfs_mode_compute(uint64_t fmode, zfs_acl_t *aclp,
mode |= S_IXUSR;
}
}
#ifdef __APPLE__
} else if (entry_type == OWNING_GROUP) {
#else
} else if (entry_type == OWNING_GROUP ||
(entry_type == ACE_IDENTIFIER_GROUP && who == fgid)) {
#endif
if ((access_mask & ACE_READ_DATA) &&
(!(seen & S_IRGRP))) {
seen |= S_IRGRP;
Expand Down Expand Up @@ -1002,8 +1009,8 @@ zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp,
boolean_t will_modify)
{
zfs_acl_t *aclp;
int aclsize;
int acl_count;
int aclsize = 0;
int acl_count = 0;
zfs_acl_node_t *aclnode;
zfs_acl_phys_t znode_acl;
int version;
Expand Down Expand Up @@ -1403,7 +1410,6 @@ zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
(zp->z_zfsvfs->z_acl_mode == ZFS_ACL_GROUPMASK), *aclp);
}
mutex_exit(&zp->z_acl_lock);

return (error);
}

Expand Down Expand Up @@ -1930,7 +1936,7 @@ zfs_addacl_trivial(znode_t *zp, ace_t *aces, int *nentries, int seen_type)
}

int
zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, umode_t obj_type,
zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
vsecattr_t *vsecp, cred_t *cr, zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp)
{
zfs_acl_t *aclp;
Expand Down Expand Up @@ -1992,16 +1998,16 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
{
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
zilog_t *zilog = zfsvfs->z_log;
ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
// ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
dmu_tx_t *tx;
int error;
zfs_acl_t *aclp;
zfs_fuid_info_t *fuidp = NULL;
boolean_t fuid_dirtied;
uint64_t acl_obj;

if (mask == 0)
return (SET_ERROR(ENOSYS));
// if (mask == 0)
// return (SET_ERROR(ENOSYS));

if (zp->z_pflags & ZFS_IMMUTABLE)
return (SET_ERROR(EPERM));
Expand All @@ -2018,10 +2024,10 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
* If ACL wide flags aren't being set then preserve any
* existing flags.
*/
if (!(vsecp->vsa_mask & VSA_ACE_ACLFLAGS)) {
aclp->z_hints |=
(zp->z_pflags & V4_ACL_WIDE_FLAGS);
}
// if (!(vsecp->vsa_mask & VSA_ACE_ACLFLAGS)) {
// aclp->z_hints |=
// (zp->z_pflags & V4_ACL_WIDE_FLAGS);
// }
top:
mutex_enter(&zp->z_acl_lock);

Expand Down
110 changes: 101 additions & 9 deletions module/os/macos/zfs/zfs_vnops_os.c
Expand Up @@ -2418,10 +2418,94 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr,
}
tx = dmu_tx_create(os);

/*
* Translate XNU ACL to ZFS ACL
*/
if (VATTR_IS_ACTIVE(vap, va_acl)) {
vsecattr_t vsecattr;
int seen_type = 0;
int aclbsize; /* size of acl list in bytes */
ace_t *aaclp;
struct kauth_acl *kauth;

printf("special xnu \n");

if ((vap->va_acl != (kauth_acl_t)KAUTH_FILESEC_NONE) &&
(vap->va_acl->acl_entrycount > 0) &&
(vap->va_acl->acl_entrycount != KAUTH_FILESEC_NOACL)) {

vsecattr.vsa_mask = VSA_ACE;
kauth = vap->va_acl;

#if HIDE_TRIVIAL_ACL
/*
* We might have to add <up to> 3 trivial acls,
* depending on what was handed to us.
*/
aclbsize = (3 + kauth->acl_entrycount) * sizeof (ace_t);
dprintf("%d ACLs, adding 3\n", kauth->acl_entrycount);
#else
aclbsize = kauth->acl_entrycount * sizeof (ace_t);
dprintf("%d ACLs\n", kauth->acl_entrycount);
#endif

vsecattr.vsa_aclentp = kmem_zalloc(aclbsize, KM_SLEEP);
aaclp = vsecattr.vsa_aclentp;
vsecattr.vsa_aclentsz = aclbsize;

#if HIDE_TRIVIAL_ACL
/*
* Add in the trivials, keep "seen_type" as a bit
* pattern of which trivials we have seen
*/
seen_type = 0;
dprintf("aces_from_acl %d entries\n",
kauth->acl_entrycount);
aces_from_acl(vsecattr.vsa_aclentp,
&vsecattr.vsa_aclcnt, kauth, &seen_type);

/* Add in trivials at end, based on the "seen_type". */
zfs_addacl_trivial(zp, vsecattr.vsa_aclentp,
&vsecattr.vsa_aclcnt, seen_type);
dprintf("together at last: %d\n", vsecattr.vsa_aclcnt);
#else
aces_from_acl(vsecattr.vsa_aclentp,
&vsecattr.vsa_aclcnt, kauth);
#endif
error = zfs_setacl(zp, &vsecattr, B_TRUE, cr);
kmem_free(aaclp, aclbsize);

} else {

seen_type = 0;
vsecattr.vsa_mask = VSA_ACE;
vsecattr.vsa_aclcnt = 0;
aclbsize = (3) * sizeof (ace_t);
vsecattr.vsa_aclentp = kmem_zalloc(aclbsize, KM_SLEEP);
aaclp = vsecattr.vsa_aclentp;
vsecattr.vsa_aclentsz = aclbsize;
/* Clearing, we need to pass in the trivials only */
zfs_addacl_trivial(zp, vsecattr.vsa_aclentp,
&vsecattr.vsa_aclcnt, seen_type);

if ((error = zfs_setacl(zp, &vsecattr, B_TRUE, cr)))
dprintf("setattr: setacl failed: %d\n", error);

kmem_free(aaclp, aclbsize);

} /* blank ACL? */
} /* VATTR_IS_ACTIVE(vap, va_acl) */


if (mask & ATTR_MODE) {
uint64_t pmode = zp->z_mode;
uint64_t acl_obj;
new_mode = (pmode & S_IFMT) | (vap->va_mode & ~S_IFMT);

/* APPLE - strip flags if NOT acl */
new_mode = pmode;
if (!VATTR_IS_ACTIVE(vap, va_acl)) {
new_mode = (pmode & S_IFMT) | (vap->va_mode & ~S_IFMT);
}

if (zp->z_zfsvfs->z_acl_mode == ZFS_ACL_RESTRICTED &&
!(zp->z_pflags & ZFS_ACL_TRIVIAL)) {
Expand Down Expand Up @@ -2569,15 +2653,23 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr,
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL,
&new_mode, sizeof (new_mode));
zp->z_mode = new_mode;
ASSERT3U((uintptr_t)aclp, !=, 0);
err = zfs_aclset_common(zp, aclp, cr, tx);
ASSERT0(err);
if (zp->z_acl_cached)
zfs_acl_free(zp->z_acl_cached);
zp->z_acl_cached = aclp;
aclp = NULL;
}

/*
* Mode change needs to trigger corresponding update to
* trivial ACLs. ACL change already does this, and another
* call to zfs_aclset_common would overwrite our explicit
* ACL changes. APPLE
*/
if (!VATTR_IS_ACTIVE(vap, va_acl)) {
ASSERT3U((uintptr_t)aclp, !=, 0);
err = zfs_aclset_common(zp, aclp, cr, tx);
ASSERT0(err);
if (zp->z_acl_cached)
zfs_acl_free(zp->z_acl_cached);
zp->z_acl_cached = aclp;
aclp = NULL;
}
}

if (mask & ATTR_ATIME) {
ZFS_TIME_ENCODE(&vap->va_atime, zp->z_atime);
Expand Down
12 changes: 3 additions & 9 deletions module/os/macos/zfs/zfs_vnops_osx.c
Expand Up @@ -1923,15 +1923,11 @@ zfs_vnop_setattr(struct vnop_setattr_args *ap)
#endif
{
DECLARE_CRED(ap);
uint_t mask;
int error = 0;
znode_t *zp = VTOZ(ap->a_vp);
vattr_t *vap = ap->a_vap;
xvattr_t xva; /* va_flags */

/* Translate OS X requested mask to ZFS */
mask = vap->va_mask;

if (VATTR_IS_ACTIVE(vap, va_access_time)) {
ZFS_TIME_ENCODE(&vap->va_access_time, zp->z_atime);
}
Expand All @@ -1944,8 +1940,6 @@ zfs_vnop_setattr(struct vnop_setattr_args *ap)
!VATTR_IS_ACTIVE(vap, va_mode)) {
uint64_t mode;

mask |= ATTR_MODE;

dprintf("fetching MODE for FLAGS or ACL\n");

if ((error = zfs_enter_verify_zp(zp->z_zfsvfs, zp, FTAG)) != 0)
Expand All @@ -1954,6 +1948,7 @@ zfs_vnop_setattr(struct vnop_setattr_args *ap)
sizeof (mode));

VATTR_RETURN(vap, va_mode, mode);
VATTR_WANTED(vap, va_mode);

zfs_exit(zp->z_zfsvfs, FTAG);
}
Expand Down Expand Up @@ -2001,7 +1996,6 @@ zfs_vnop_setattr(struct vnop_setattr_args *ap)

}


/* Map OS X file flags to zfs file flags */
error = zfs_setbsdflags(zp, vap->va_flags, &xva);
if (!error) {
Expand Down Expand Up @@ -2034,8 +2028,8 @@ zfs_vnop_setattr(struct vnop_setattr_args *ap)
error = zfs_setattr(VTOZ(ap->a_vp), vap, /* flag */0, cr,
NULL);

dprintf("vnop_setattr: called on vp %p with mask %04x, err=%d\n",
ap->a_vp, mask, error);
dprintf("vnop_setattr: called on vp %p with mask %llx, err=%d\n",
ap->a_vp, vap->va_mask, error);

if (!error) {
/* If successful, tell OS X which fields ZFS set. */
Expand Down
1 change: 0 additions & 1 deletion module/os/macos/zfs/zfs_vnops_osx_lib.c
Expand Up @@ -202,7 +202,6 @@ zfs_getattr_znode_unlocked(struct vnode *vp, vattr_t *vap)
} else {
VATTR_SET_SUPPORTED(vap, va_acl);
}

}

mutex_enter(&zp->z_lock);
Expand Down

0 comments on commit d37bb30

Please sign in to comment.