Fix namespace handling in zpl_permission (#246)
This commit fixes user / idmap namespaces in zpl_permission. ZFS updates to address kernel changes were subtly broken and passing the wrong namespace to generic_permission(). Since zpl_permission was initially written, zfs_zaccess() has become idmap-aware. This commit switches from using zfs_access to zfs_zaccess() and improves zfs_zaccess_aces_check() so that uids / gids in ACL entries are converted via idmap configuration prior to checking access. Signed-off-by: Andrew Walker <awalker@ixsystems.com>
This commit is contained in:
parent
072c9ab66b
commit
e11753560b
|
@ -2442,8 +2442,11 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||||
break;
|
break;
|
||||||
case OWNING_GROUP:
|
case OWNING_GROUP:
|
||||||
who = gowner;
|
who = gowner;
|
||||||
zfs_fallthrough;
|
checkit = zfs_groupmember(zfsvfs, who, cr);
|
||||||
|
break;
|
||||||
case ACE_IDENTIFIER_GROUP:
|
case ACE_IDENTIFIER_GROUP:
|
||||||
|
who = zfs_gid_to_vfsgid(mnt_ns, zfs_i_user_ns(ZTOI(zp)),
|
||||||
|
who);
|
||||||
checkit = zfs_groupmember(zfsvfs, who, cr);
|
checkit = zfs_groupmember(zfsvfs, who, cr);
|
||||||
break;
|
break;
|
||||||
case ACE_EVERYONE:
|
case ACE_EVERYONE:
|
||||||
|
@ -2454,6 +2457,8 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||||
default:
|
default:
|
||||||
if (entry_type == 0) {
|
if (entry_type == 0) {
|
||||||
uid_t newid;
|
uid_t newid;
|
||||||
|
who = zfs_uid_to_vfsuid(mnt_ns,
|
||||||
|
zfs_i_user_ns(ZTOI(zp)), who);
|
||||||
|
|
||||||
newid = zfs_fuid_map_id(zfsvfs, who, cr,
|
newid = zfs_fuid_map_id(zfsvfs, who, cr,
|
||||||
ZFS_ACE_USER);
|
ZFS_ACE_USER);
|
||||||
|
|
|
@ -1507,6 +1507,7 @@ zpl_permission(struct inode *ip, int mask)
|
||||||
{
|
{
|
||||||
int to_check = 0, i, ret;
|
int to_check = 0, i, ret;
|
||||||
cred_t *cr = NULL;
|
cred_t *cr = NULL;
|
||||||
|
zfsvfs_t *zfsvfs = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If NFSv4 ACLs are not being used, go back to
|
* If NFSv4 ACLs are not being used, go back to
|
||||||
|
@ -1516,9 +1517,10 @@ zpl_permission(struct inode *ip, int mask)
|
||||||
*/
|
*/
|
||||||
if ((ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_NFSV4) ||
|
if ((ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_NFSV4) ||
|
||||||
((ITOZ(ip)->z_pflags & ZFS_ACL_TRIVIAL && GENERIC_MASK(mask)))) {
|
((ITOZ(ip)->z_pflags & ZFS_ACL_TRIVIAL && GENERIC_MASK(mask)))) {
|
||||||
#if (defined(HAVE_IOPS_PERMISSION_USERNS) || \
|
#if defined(HAVE_IOPS_PERMISSION_USERNS)
|
||||||
defined(HAVE_IOPS_PERMISSION_IDMAP))
|
return (generic_permission(userns, ip, mask));
|
||||||
return (generic_permission(zfs_init_idmap, ip, mask));
|
#elif defined(HAVE_IOPS_PERMISSION_IDMAP)
|
||||||
|
return (generic_permission(idmap, ip, mask));
|
||||||
#else
|
#else
|
||||||
return (generic_permission(ip, mask));
|
return (generic_permission(ip, mask));
|
||||||
#endif
|
#endif
|
||||||
|
@ -1535,9 +1537,10 @@ zpl_permission(struct inode *ip, int mask)
|
||||||
* NFSv4 ACE. Pass back to default kernel permissions check.
|
* NFSv4 ACE. Pass back to default kernel permissions check.
|
||||||
*/
|
*/
|
||||||
if (to_check == 0) {
|
if (to_check == 0) {
|
||||||
#if (defined(HAVE_IOPS_PERMISSION_USERNS) || \
|
#if defined(HAVE_IOPS_PERMISSION_USERNS)
|
||||||
defined(HAVE_IOPS_PERMISSION_IDMAP))
|
return (generic_permission(userns, ip, mask));
|
||||||
return (generic_permission(zfs_init_idmap, ip, mask));
|
#elif defined(HAVE_IOPS_PERMISSION_IDMAP)
|
||||||
|
return (generic_permission(idmap, ip, mask));
|
||||||
#else
|
#else
|
||||||
return (generic_permission(ip, mask));
|
return (generic_permission(ip, mask));
|
||||||
#endif
|
#endif
|
||||||
|
@ -1614,7 +1617,24 @@ zpl_permission(struct inode *ip, int mask)
|
||||||
return (-ECHILD);
|
return (-ECHILD);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = -zfs_access(ITOZ(ip), to_check, V_ACE_MASK, cr);
|
zfsvfs = ZTOZSB(ITOZ(ip));
|
||||||
|
|
||||||
|
if ((ret = -zfs_enter_verify_zp(zfsvfs, ITOZ(ip), FTAG)) != 0)
|
||||||
|
return (ret);
|
||||||
|
|
||||||
|
#if defined(HAVE_IOPS_PERMISSION_USERNS)
|
||||||
|
ret = -zfs_zaccess(ITOZ(ip), to_check, V_ACE_MASK, B_FALSE, cr,
|
||||||
|
userns);
|
||||||
|
#elif defined(HAVE_IOPS_PERMISSION_IDMAP)
|
||||||
|
ret = -zfs_zaccess(ITOZ(ip), to_check, V_ACE_MASK, B_FALSE, cr,
|
||||||
|
idmap);
|
||||||
|
#else
|
||||||
|
ret = -zfs_zaccess(ITOZ(ip), to_check, V_ACE_MASK, B_FALSE, cr,
|
||||||
|
zfs_init_idmap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
zfs_exit(zfsvfs, FTAG);
|
||||||
|
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue