mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Support idmapped mount
Adds support for idmapped mounts. Supported as of Linux 5.12 this functionality allows user and group IDs to be remapped without changing their state on disk. This can be useful for portable home directories and a variety of container related use cases. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Youzhong Yang <yyang@mathworks.com> Closes #12923 Closes #13671
This commit is contained in:
@@ -1619,7 +1619,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
|
||||
*/
|
||||
int
|
||||
zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
|
||||
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids, zuserns_t *mnt_ns)
|
||||
{
|
||||
int error;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
@@ -1789,7 +1789,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
if (mask == 0)
|
||||
return (SET_ERROR(ENOSYS));
|
||||
|
||||
if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)))
|
||||
if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr, NULL)))
|
||||
return (error);
|
||||
|
||||
mutex_enter(&zp->z_acl_lock);
|
||||
@@ -1952,7 +1952,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
if (zp->z_pflags & ZFS_IMMUTABLE)
|
||||
return (SET_ERROR(EPERM));
|
||||
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, NULL)))
|
||||
return (error);
|
||||
|
||||
error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, cr, &fuidp,
|
||||
@@ -2341,7 +2341,8 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
|
||||
* can define any form of access.
|
||||
*/
|
||||
int
|
||||
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr,
|
||||
zuserns_t *mnt_ns)
|
||||
{
|
||||
uint32_t working_mode;
|
||||
int error;
|
||||
@@ -2471,9 +2472,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
* NFSv4-style ZFS ACL format and call zfs_zaccess()
|
||||
*/
|
||||
int
|
||||
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
|
||||
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr,
|
||||
zuserns_t *mnt_ns)
|
||||
{
|
||||
return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
|
||||
return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr,
|
||||
mnt_ns));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2484,7 +2487,7 @@ zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
|
||||
{
|
||||
int v4_mode = zfs_unix_to_v4(mode >> 6);
|
||||
|
||||
return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
|
||||
return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr, NULL));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2540,7 +2543,7 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp,
|
||||
*
|
||||
*/
|
||||
int
|
||||
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
|
||||
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
uint32_t dzp_working_mode = 0;
|
||||
uint32_t zp_working_mode = 0;
|
||||
@@ -2627,7 +2630,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
|
||||
|
||||
int
|
||||
zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
|
||||
znode_t *tzp, cred_t *cr)
|
||||
znode_t *tzp, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
int add_perm;
|
||||
int error;
|
||||
@@ -2647,7 +2650,8 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
|
||||
* to another.
|
||||
*/
|
||||
if (ZTOV(szp)->v_type == VDIR && ZTOV(sdzp) != ZTOV(tdzp)) {
|
||||
if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr)))
|
||||
if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr,
|
||||
mnt_ns)))
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -2657,19 +2661,19 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
|
||||
* If that succeeds then check for add_file/add_subdir permissions
|
||||
*/
|
||||
|
||||
if ((error = zfs_zaccess_delete(sdzp, szp, cr)))
|
||||
if ((error = zfs_zaccess_delete(sdzp, szp, cr, mnt_ns)))
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* If we have a tzp, see if we can delete it?
|
||||
*/
|
||||
if (tzp && (error = zfs_zaccess_delete(tdzp, tzp, cr)))
|
||||
if (tzp && (error = zfs_zaccess_delete(tdzp, tzp, cr, mnt_ns)))
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* Now check for add permissions
|
||||
*/
|
||||
error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
|
||||
error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr, mnt_ns);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -809,7 +809,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xvpp, cred_t *cr)
|
||||
*xvpp = NULL;
|
||||
|
||||
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
|
||||
&acl_ids)) != 0)
|
||||
&acl_ids, NULL)) != 0)
|
||||
return (error);
|
||||
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, 0)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
@@ -955,7 +955,7 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
|
||||
|
||||
if ((uid = crgetuid(cr)) == downer || uid == fowner ||
|
||||
(ZTOV(zp)->v_type == VREG &&
|
||||
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0))
|
||||
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL) == 0))
|
||||
return (0);
|
||||
else
|
||||
return (secpolicy_vnode_remove(ZTOV(zp), cr));
|
||||
|
||||
@@ -837,7 +837,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
|
||||
/*
|
||||
* Do we have permission to get into attribute directory?
|
||||
*/
|
||||
error = zfs_zaccess(zp, ACE_EXECUTE, 0, B_FALSE, cr);
|
||||
error = zfs_zaccess(zp, ACE_EXECUTE, 0, B_FALSE, cr, NULL);
|
||||
if (error) {
|
||||
vrele(ZTOV(zp));
|
||||
}
|
||||
@@ -856,7 +856,8 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
|
||||
cnp->cn_flags &= ~NOEXECCHECK;
|
||||
} else
|
||||
#endif
|
||||
if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr,
|
||||
NULL))) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -1036,6 +1037,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
|
||||
* flag - large file flag [UNUSED].
|
||||
* ct - caller context
|
||||
* vsecp - ACL to be set
|
||||
* mnt_ns - Unused on FreeBSD
|
||||
*
|
||||
* OUT: vpp - vnode of created or trunc'd entry.
|
||||
*
|
||||
@@ -1047,7 +1049,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
|
||||
*/
|
||||
int
|
||||
zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
||||
znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp)
|
||||
znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp, zuserns_t *mnt_ns)
|
||||
{
|
||||
(void) excl, (void) mode, (void) flag;
|
||||
znode_t *zp;
|
||||
@@ -1110,7 +1112,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
||||
* Create a new file object and update the directory
|
||||
* to reference it.
|
||||
*/
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1126,7 +1128,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode,
|
||||
}
|
||||
|
||||
if ((error = zfs_acl_ids_create(dzp, 0, vap,
|
||||
cr, vsecp, &acl_ids)) != 0)
|
||||
cr, vsecp, &acl_ids, NULL)) != 0)
|
||||
goto out;
|
||||
|
||||
if (S_ISREG(vap->va_mode) || S_ISDIR(vap->va_mode))
|
||||
@@ -1231,7 +1233,7 @@ zfs_remove_(vnode_t *dvp, vnode_t *vp, const char *name, cred_t *cr)
|
||||
xattr_obj = 0;
|
||||
xzp = NULL;
|
||||
|
||||
if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
|
||||
if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1387,6 +1389,7 @@ zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags)
|
||||
* ct - caller context
|
||||
* flags - case flags
|
||||
* vsecp - ACL to be set
|
||||
* mnt_ns - Unused on FreeBSD
|
||||
*
|
||||
* OUT: vpp - vnode of created directory.
|
||||
*
|
||||
@@ -1398,7 +1401,7 @@ zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags)
|
||||
*/
|
||||
int
|
||||
zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
||||
cred_t *cr, int flags, vsecattr_t *vsecp)
|
||||
cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns)
|
||||
{
|
||||
(void) flags, (void) vsecp;
|
||||
znode_t *zp;
|
||||
@@ -1447,7 +1450,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
||||
}
|
||||
|
||||
if ((error = zfs_acl_ids_create(dzp, 0, vap, cr,
|
||||
NULL, &acl_ids)) != 0) {
|
||||
NULL, &acl_ids, NULL)) != 0) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -1468,7 +1471,8 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp,
|
||||
}
|
||||
ASSERT3P(zp, ==, NULL);
|
||||
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr,
|
||||
mnt_ns))) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
@@ -1585,7 +1589,7 @@ zfs_rmdir_(vnode_t *dvp, vnode_t *vp, const char *name, cred_t *cr)
|
||||
zilog = zfsvfs->z_log;
|
||||
|
||||
|
||||
if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
|
||||
if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1976,7 +1980,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr)
|
||||
if (!(zp->z_pflags & ZFS_ACL_TRIVIAL) &&
|
||||
(vap->va_uid != crgetuid(cr))) {
|
||||
if ((error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, 0,
|
||||
skipaclchk, cr))) {
|
||||
skipaclchk, cr, NULL))) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -2142,7 +2146,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr)
|
||||
* flags - ATTR_UTIME set if non-default time values provided.
|
||||
* - ATTR_NOACLCHECK (CIFS context only).
|
||||
* cr - credentials of caller.
|
||||
* ct - caller context
|
||||
* mnt_ns - Unused on FreeBSD
|
||||
*
|
||||
* RETURN: 0 on success, error code on failure.
|
||||
*
|
||||
@@ -2150,7 +2154,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr)
|
||||
* vp - ctime updated, mtime updated if size changed.
|
||||
*/
|
||||
int
|
||||
zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
|
||||
zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
vnode_t *vp = ZTOV(zp);
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
@@ -2322,7 +2326,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
|
||||
XVA_ISSET_REQ(xvap, XAT_CREATETIME) ||
|
||||
XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) {
|
||||
need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0,
|
||||
skipaclchk, cr);
|
||||
skipaclchk, cr, mnt_ns);
|
||||
}
|
||||
|
||||
if (mask & (AT_UID|AT_GID)) {
|
||||
@@ -2359,7 +2363,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
|
||||
((idmask == AT_UID) && take_owner) ||
|
||||
((idmask == AT_GID) && take_group)) {
|
||||
if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0,
|
||||
skipaclchk, cr) == 0) {
|
||||
skipaclchk, cr, mnt_ns) == 0) {
|
||||
/*
|
||||
* Remove setuid/setgid for non-privileged users
|
||||
*/
|
||||
@@ -2468,7 +2472,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
|
||||
}
|
||||
|
||||
if (mask & AT_MODE) {
|
||||
if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) {
|
||||
if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr,
|
||||
mnt_ns) == 0) {
|
||||
err = secpolicy_setid_setsticky_clear(vp, vap,
|
||||
&oldva, cr);
|
||||
if (err) {
|
||||
@@ -3264,7 +3269,7 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp,
|
||||
* Note that if target and source are the same, this can be
|
||||
* done in a single check.
|
||||
*/
|
||||
if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr)))
|
||||
if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr, NULL)))
|
||||
goto out;
|
||||
|
||||
if ((*svpp)->v_type == VDIR) {
|
||||
@@ -3415,7 +3420,7 @@ out:
|
||||
|
||||
int
|
||||
zfs_rename(znode_t *sdzp, const char *sname, znode_t *tdzp, const char *tname,
|
||||
cred_t *cr, int flags)
|
||||
cred_t *cr, int flags, zuserns_t *mnt_ns)
|
||||
{
|
||||
struct componentname scn, tcn;
|
||||
vnode_t *sdvp, *tdvp;
|
||||
@@ -3460,6 +3465,7 @@ fail:
|
||||
* cr - credentials of caller.
|
||||
* ct - caller context
|
||||
* flags - case flags
|
||||
* mnt_ns - Unused on FreeBSD
|
||||
*
|
||||
* RETURN: 0 on success, error code on failure.
|
||||
*
|
||||
@@ -3468,7 +3474,7 @@ fail:
|
||||
*/
|
||||
int
|
||||
zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
|
||||
const char *link, znode_t **zpp, cred_t *cr, int flags)
|
||||
const char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns)
|
||||
{
|
||||
(void) flags;
|
||||
znode_t *zp;
|
||||
@@ -3499,7 +3505,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
|
||||
}
|
||||
|
||||
if ((error = zfs_acl_ids_create(dzp, 0,
|
||||
vap, cr, NULL, &acl_ids)) != 0) {
|
||||
vap, cr, NULL, &acl_ids, NULL)) != 0) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -3514,7 +3520,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
|
||||
return (error);
|
||||
}
|
||||
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
@@ -3730,7 +3736,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, const char *name, cred_t *cr,
|
||||
return (SET_ERROR(EPERM));
|
||||
}
|
||||
|
||||
if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr, NULL))) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -3831,7 +3837,7 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
|
||||
* On Linux we can get here through truncate_range() which
|
||||
* operates directly on inodes, so we need to check access rights.
|
||||
*/
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL))) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -4607,7 +4613,7 @@ zfs_freebsd_create(struct vop_create_args *ap)
|
||||
*ap->a_vpp = NULL;
|
||||
|
||||
rc = zfs_create(VTOZ(ap->a_dvp), cnp->cn_nameptr, vap, 0, mode,
|
||||
&zp, cnp->cn_cred, 0 /* flag */, NULL /* vsecattr */);
|
||||
&zp, cnp->cn_cred, 0 /* flag */, NULL /* vsecattr */, NULL);
|
||||
if (rc == 0)
|
||||
*ap->a_vpp = ZTOV(zp);
|
||||
if (zfsvfs->z_use_namecache &&
|
||||
@@ -4661,7 +4667,7 @@ zfs_freebsd_mkdir(struct vop_mkdir_args *ap)
|
||||
*ap->a_vpp = NULL;
|
||||
|
||||
rc = zfs_mkdir(VTOZ(ap->a_dvp), ap->a_cnp->cn_nameptr, vap, &zp,
|
||||
ap->a_cnp->cn_cred, 0, NULL);
|
||||
ap->a_cnp->cn_cred, 0, NULL, NULL);
|
||||
|
||||
if (rc == 0)
|
||||
*ap->a_vpp = ZTOV(zp);
|
||||
@@ -4914,7 +4920,7 @@ zfs_freebsd_setattr(struct vop_setattr_args *ap)
|
||||
xvap.xva_vattr.va_mask |= AT_XVATTR;
|
||||
XVA_SET_REQ(&xvap, XAT_CREATETIME);
|
||||
}
|
||||
return (zfs_setattr(VTOZ(vp), (vattr_t *)&xvap, 0, cred));
|
||||
return (zfs_setattr(VTOZ(vp), (vattr_t *)&xvap, 0, cred, NULL));
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@@ -4985,7 +4991,7 @@ zfs_freebsd_symlink(struct vop_symlink_args *ap)
|
||||
*ap->a_vpp = NULL;
|
||||
|
||||
rc = zfs_symlink(VTOZ(ap->a_dvp), cnp->cn_nameptr, vap,
|
||||
ap->a_target, &zp, cnp->cn_cred, 0 /* flags */);
|
||||
ap->a_target, &zp, cnp->cn_cred, 0 /* flags */, NULL);
|
||||
if (rc == 0) {
|
||||
*ap->a_vpp = ZTOV(zp);
|
||||
ASSERT_VOP_ELOCKED(ZTOV(zp), __func__);
|
||||
|
||||
@@ -298,7 +298,7 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
|
||||
sharezp->z_is_sa = zfsvfs->z_use_sa;
|
||||
|
||||
VERIFY0(zfs_acl_ids_create(sharezp, IS_ROOT_NODE, &vattr,
|
||||
kcred, NULL, &acl_ids));
|
||||
kcred, NULL, &acl_ids, NULL));
|
||||
zfs_mknode(sharezp, &vattr, tx, kcred, IS_ROOT_NODE, &zp, &acl_ids);
|
||||
ASSERT3P(zp, ==, sharezp);
|
||||
POINTER_INVALIDATE(&sharezp->z_zfsvfs);
|
||||
@@ -1773,7 +1773,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
|
||||
|
||||
rootzp->z_zfsvfs = zfsvfs;
|
||||
VERIFY0(zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
|
||||
cr, NULL, &acl_ids));
|
||||
cr, NULL, &acl_ids, NULL));
|
||||
zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids);
|
||||
ASSERT3P(zp, ==, rootzp);
|
||||
error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx);
|
||||
|
||||
@@ -214,8 +214,9 @@ secpolicy_vnode_setid_retain(struct znode *zp __maybe_unused, const cred_t *cr,
|
||||
* Determine that subject can set the file setgid flag.
|
||||
*/
|
||||
int
|
||||
secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid)
|
||||
secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid, zuserns_t *mnt_ns)
|
||||
{
|
||||
gid = zfs_gid_into_mnt(mnt_ns, gid);
|
||||
#if defined(CONFIG_USER_NS)
|
||||
if (!kgid_has_mapping(cr->user_ns, SGID_TO_KGID(gid)))
|
||||
return (EPERM);
|
||||
@@ -284,8 +285,10 @@ secpolicy_setid_clear(vattr_t *vap, cred_t *cr)
|
||||
* Determine that subject can set the file setid flags.
|
||||
*/
|
||||
static int
|
||||
secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner)
|
||||
secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner, zuserns_t *mnt_ns)
|
||||
{
|
||||
owner = zfs_uid_into_mnt(mnt_ns, owner);
|
||||
|
||||
if (crgetuid(cr) == owner)
|
||||
return (0);
|
||||
|
||||
@@ -310,13 +313,13 @@ secpolicy_vnode_stky_modify(const cred_t *cr)
|
||||
|
||||
int
|
||||
secpolicy_setid_setsticky_clear(struct inode *ip, vattr_t *vap,
|
||||
const vattr_t *ovap, cred_t *cr)
|
||||
const vattr_t *ovap, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((vap->va_mode & S_ISUID) != 0 &&
|
||||
(error = secpolicy_vnode_setid_modify(cr,
|
||||
ovap->va_uid)) != 0) {
|
||||
ovap->va_uid, mnt_ns)) != 0) {
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -334,7 +337,7 @@ secpolicy_setid_setsticky_clear(struct inode *ip, vattr_t *vap,
|
||||
* group-id bit.
|
||||
*/
|
||||
if ((vap->va_mode & S_ISGID) != 0 &&
|
||||
secpolicy_vnode_setids_setgids(cr, ovap->va_gid) != 0) {
|
||||
secpolicy_vnode_setids_setgids(cr, ovap->va_gid, mnt_ns) != 0) {
|
||||
vap->va_mode &= ~S_ISGID;
|
||||
}
|
||||
|
||||
|
||||
@@ -1802,7 +1802,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, umode_t va_mode, zfs_acl_t *paclp,
|
||||
*/
|
||||
int
|
||||
zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
|
||||
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids, zuserns_t *mnt_ns)
|
||||
{
|
||||
int error;
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
|
||||
@@ -1889,8 +1889,9 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||
acl_ids->z_mode |= S_ISGID;
|
||||
} else {
|
||||
if ((acl_ids->z_mode & S_ISGID) &&
|
||||
secpolicy_vnode_setids_setgids(cr, gid) != 0)
|
||||
secpolicy_vnode_setids_setgids(cr, gid, mnt_ns) != 0) {
|
||||
acl_ids->z_mode &= ~S_ISGID;
|
||||
}
|
||||
}
|
||||
|
||||
if (acl_ids->z_aclp == NULL) {
|
||||
@@ -1978,7 +1979,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
if (mask == 0)
|
||||
return (SET_ERROR(ENOSYS));
|
||||
|
||||
if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)))
|
||||
if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr, NULL)))
|
||||
return (error);
|
||||
|
||||
mutex_enter(&zp->z_acl_lock);
|
||||
@@ -2137,7 +2138,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
if (zp->z_pflags & ZFS_IMMUTABLE)
|
||||
return (SET_ERROR(EPERM));
|
||||
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, NULL)))
|
||||
return (error);
|
||||
|
||||
error = zfs_vsec_2_aclp(zfsvfs, ZTOI(zp)->i_mode, vsecp, cr, &fuidp,
|
||||
@@ -2283,7 +2284,7 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
|
||||
*/
|
||||
static int
|
||||
zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||
boolean_t anyaccess, cred_t *cr)
|
||||
boolean_t anyaccess, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(zp);
|
||||
zfs_acl_t *aclp;
|
||||
@@ -2299,7 +2300,13 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||
uid_t gowner;
|
||||
uid_t fowner;
|
||||
|
||||
zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
|
||||
if (mnt_ns) {
|
||||
fowner = zfs_uid_into_mnt(mnt_ns,
|
||||
KUID_TO_SUID(ZTOI(zp)->i_uid));
|
||||
gowner = zfs_gid_into_mnt(mnt_ns,
|
||||
KGID_TO_SGID(ZTOI(zp)->i_gid));
|
||||
} else
|
||||
zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
|
||||
|
||||
mutex_enter(&zp->z_acl_lock);
|
||||
|
||||
@@ -2410,7 +2417,7 @@ zfs_has_access(znode_t *zp, cred_t *cr)
|
||||
{
|
||||
uint32_t have = ACE_ALL_PERMS;
|
||||
|
||||
if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) {
|
||||
if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr, NULL) != 0) {
|
||||
uid_t owner;
|
||||
|
||||
owner = zfs_fuid_map_id(ZTOZSB(zp),
|
||||
@@ -2440,7 +2447,8 @@ zfs_has_access(znode_t *zp, cred_t *cr)
|
||||
* we want to avoid that here.
|
||||
*/
|
||||
static int
|
||||
zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr)
|
||||
zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr,
|
||||
zuserns_t *mnt_ns)
|
||||
{
|
||||
int err, mask;
|
||||
int unmapped = 0;
|
||||
@@ -2454,7 +2462,10 @@ zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr)
|
||||
}
|
||||
|
||||
#if defined(HAVE_IOPS_PERMISSION_USERNS)
|
||||
err = generic_permission(cr->user_ns, ZTOI(zp), mask);
|
||||
if (mnt_ns)
|
||||
err = generic_permission(mnt_ns, ZTOI(zp), mask);
|
||||
else
|
||||
err = generic_permission(cr->user_ns, ZTOI(zp), mask);
|
||||
#else
|
||||
err = generic_permission(ZTOI(zp), mask);
|
||||
#endif
|
||||
@@ -2469,7 +2480,7 @@ zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr)
|
||||
|
||||
static int
|
||||
zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
|
||||
boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
|
||||
boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(zp);
|
||||
int err;
|
||||
@@ -2519,20 +2530,20 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
|
||||
}
|
||||
|
||||
if (zp->z_pflags & ZFS_ACL_TRIVIAL)
|
||||
return (zfs_zaccess_trivial(zp, working_mode, cr));
|
||||
return (zfs_zaccess_trivial(zp, working_mode, cr, mnt_ns));
|
||||
|
||||
return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr));
|
||||
return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr, mnt_ns));
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs,
|
||||
cred_t *cr)
|
||||
cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
if (*working_mode != ACE_WRITE_DATA)
|
||||
return (SET_ERROR(EACCES));
|
||||
|
||||
return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode,
|
||||
check_privs, B_FALSE, cr));
|
||||
check_privs, B_FALSE, cr, mnt_ns));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -2599,7 +2610,7 @@ slow:
|
||||
DTRACE_PROBE(zfs__fastpath__execute__access__miss);
|
||||
if ((error = zfs_enter(ZTOZSB(zdp), FTAG)) != 0)
|
||||
return (error);
|
||||
error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr);
|
||||
error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr, NULL);
|
||||
zfs_exit(ZTOZSB(zdp), FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -2611,7 +2622,8 @@ slow:
|
||||
* can define any form of access.
|
||||
*/
|
||||
int
|
||||
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr,
|
||||
zuserns_t *mnt_ns)
|
||||
{
|
||||
uint32_t working_mode;
|
||||
int error;
|
||||
@@ -2650,8 +2662,9 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
}
|
||||
}
|
||||
|
||||
owner = zfs_fuid_map_id(ZTOZSB(zp), KUID_TO_SUID(ZTOI(zp)->i_uid),
|
||||
cr, ZFS_OWNER);
|
||||
owner = zfs_uid_into_mnt(mnt_ns, KUID_TO_SUID(ZTOI(zp)->i_uid));
|
||||
owner = zfs_fuid_map_id(ZTOZSB(zp), owner, cr, ZFS_OWNER);
|
||||
|
||||
/*
|
||||
* Map the bits required to the standard inode flags
|
||||
* S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits. Map the bits
|
||||
@@ -2676,7 +2689,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
needed_bits |= S_IXUSR;
|
||||
|
||||
if ((error = zfs_zaccess_common(check_zp, mode, &working_mode,
|
||||
&check_privs, skipaclchk, cr)) == 0) {
|
||||
&check_privs, skipaclchk, cr, mnt_ns)) == 0) {
|
||||
if (is_attr)
|
||||
zrele(xzp);
|
||||
return (secpolicy_vnode_access2(cr, ZTOI(zp), owner,
|
||||
@@ -2690,7 +2703,8 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
}
|
||||
|
||||
if (error && (flags & V_APPEND)) {
|
||||
error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr);
|
||||
error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr,
|
||||
mnt_ns);
|
||||
}
|
||||
|
||||
if (error && check_privs) {
|
||||
@@ -2757,9 +2771,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
||||
* NFSv4-style ZFS ACL format and call zfs_zaccess()
|
||||
*/
|
||||
int
|
||||
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
|
||||
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr,
|
||||
zuserns_t *mnt_ns)
|
||||
{
|
||||
return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
|
||||
return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr,
|
||||
mnt_ns));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2770,7 +2786,7 @@ zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
|
||||
{
|
||||
int v4_mode = zfs_unix_to_v4(mode >> 6);
|
||||
|
||||
return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
|
||||
return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr, NULL));
|
||||
}
|
||||
|
||||
/* See zfs_zaccess_delete() */
|
||||
@@ -2847,7 +2863,7 @@ static const boolean_t zfs_write_implies_delete_child = B_TRUE;
|
||||
* zfs_write_implies_delete_child
|
||||
*/
|
||||
int
|
||||
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
|
||||
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
uint32_t wanted_dirperms;
|
||||
uint32_t dzp_working_mode = 0;
|
||||
@@ -2874,7 +2890,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
|
||||
* (This is part of why we're checking the target first.)
|
||||
*/
|
||||
zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode,
|
||||
&zpcheck_privs, B_FALSE, cr);
|
||||
&zpcheck_privs, B_FALSE, cr, mnt_ns);
|
||||
if (zp_error == EACCES) {
|
||||
/* We hit a DENY ACE. */
|
||||
if (!zpcheck_privs)
|
||||
@@ -2896,7 +2912,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
|
||||
if (zfs_write_implies_delete_child)
|
||||
wanted_dirperms |= ACE_WRITE_DATA;
|
||||
dzp_error = zfs_zaccess_common(dzp, wanted_dirperms,
|
||||
&dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
|
||||
&dzp_working_mode, &dzpcheck_privs, B_FALSE, cr, mnt_ns);
|
||||
if (dzp_error == EACCES) {
|
||||
/* We hit a DENY ACE. */
|
||||
if (!dzpcheck_privs)
|
||||
@@ -2978,7 +2994,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
|
||||
|
||||
int
|
||||
zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
|
||||
znode_t *tzp, cred_t *cr)
|
||||
znode_t *tzp, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
int add_perm;
|
||||
int error;
|
||||
@@ -3000,21 +3016,21 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
|
||||
* If that succeeds then check for add_file/add_subdir permissions
|
||||
*/
|
||||
|
||||
if ((error = zfs_zaccess_delete(sdzp, szp, cr)))
|
||||
if ((error = zfs_zaccess_delete(sdzp, szp, cr, mnt_ns)))
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* If we have a tzp, see if we can delete it?
|
||||
*/
|
||||
if (tzp) {
|
||||
if ((error = zfs_zaccess_delete(tdzp, tzp, cr)))
|
||||
if ((error = zfs_zaccess_delete(tdzp, tzp, cr, mnt_ns)))
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check for add permissions
|
||||
*/
|
||||
error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
|
||||
error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr, mnt_ns);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -1066,11 +1066,12 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xzpp, cred_t *cr)
|
||||
|
||||
*xzpp = NULL;
|
||||
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)))
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr,
|
||||
NULL)))
|
||||
return (error);
|
||||
|
||||
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
|
||||
&acl_ids)) != 0)
|
||||
&acl_ids, NULL)) != 0)
|
||||
return (error);
|
||||
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, zp->z_projid)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
@@ -1218,7 +1219,7 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
|
||||
cr, ZFS_OWNER);
|
||||
|
||||
if ((uid = crgetuid(cr)) == downer || uid == fowner ||
|
||||
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0)
|
||||
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL) == 0)
|
||||
return (0);
|
||||
else
|
||||
return (secpolicy_vnode_remove(cr));
|
||||
|
||||
@@ -476,7 +476,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
|
||||
*/
|
||||
|
||||
if ((error = zfs_zaccess(*zpp, ACE_EXECUTE, 0,
|
||||
B_TRUE, cr))) {
|
||||
B_TRUE, cr, NULL))) {
|
||||
zrele(*zpp);
|
||||
*zpp = NULL;
|
||||
}
|
||||
@@ -494,7 +494,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
|
||||
* Check accessibility of directory.
|
||||
*/
|
||||
|
||||
if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr, NULL))) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -526,6 +526,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
|
||||
* cr - credentials of caller.
|
||||
* flag - file flag.
|
||||
* vsecp - ACL to be set
|
||||
* mnt_ns - user namespace of the mount
|
||||
*
|
||||
* OUT: zpp - znode of created or trunc'd entry.
|
||||
*
|
||||
@@ -537,7 +538,8 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr,
|
||||
*/
|
||||
int
|
||||
zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
|
||||
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp)
|
||||
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
|
||||
zuserns_t *mnt_ns)
|
||||
{
|
||||
znode_t *zp;
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
|
||||
@@ -624,7 +626,8 @@ top:
|
||||
* Create a new file object and update the directory
|
||||
* to reference it.
|
||||
*/
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr,
|
||||
mnt_ns))) {
|
||||
if (have_acl)
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
goto out;
|
||||
@@ -643,7 +646,7 @@ top:
|
||||
}
|
||||
|
||||
if (!have_acl && (error = zfs_acl_ids_create(dzp, 0, vap,
|
||||
cr, vsecp, &acl_ids)) != 0)
|
||||
cr, vsecp, &acl_ids, mnt_ns)) != 0)
|
||||
goto out;
|
||||
have_acl = B_TRUE;
|
||||
|
||||
@@ -738,7 +741,8 @@ top:
|
||||
/*
|
||||
* Verify requested access to file.
|
||||
*/
|
||||
if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr))) {
|
||||
if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr,
|
||||
mnt_ns))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -782,7 +786,8 @@ out:
|
||||
|
||||
int
|
||||
zfs_tmpfile(struct inode *dip, vattr_t *vap, int excl,
|
||||
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp)
|
||||
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp,
|
||||
zuserns_t *mnt_ns)
|
||||
{
|
||||
(void) excl, (void) mode, (void) flag;
|
||||
znode_t *zp = NULL, *dzp = ITOZ(dip);
|
||||
@@ -829,14 +834,14 @@ top:
|
||||
* Create a new file object and update the directory
|
||||
* to reference it.
|
||||
*/
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) {
|
||||
if (have_acl)
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!have_acl && (error = zfs_acl_ids_create(dzp, 0, vap,
|
||||
cr, vsecp, &acl_ids)) != 0)
|
||||
cr, vsecp, &acl_ids, mnt_ns)) != 0)
|
||||
goto out;
|
||||
have_acl = B_TRUE;
|
||||
|
||||
@@ -967,7 +972,7 @@ top:
|
||||
return (error);
|
||||
}
|
||||
|
||||
if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
|
||||
if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1147,6 +1152,7 @@ out:
|
||||
* cr - credentials of caller.
|
||||
* flags - case flags.
|
||||
* vsecp - ACL to be set
|
||||
* mnt_ns - user namespace of the mount
|
||||
*
|
||||
* OUT: zpp - znode of created directory.
|
||||
*
|
||||
@@ -1159,7 +1165,7 @@ out:
|
||||
*/
|
||||
int
|
||||
zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
|
||||
cred_t *cr, int flags, vsecattr_t *vsecp)
|
||||
cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns)
|
||||
{
|
||||
znode_t *zp;
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(dzp);
|
||||
@@ -1216,7 +1222,7 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
|
||||
}
|
||||
|
||||
if ((error = zfs_acl_ids_create(dzp, 0, vap, cr,
|
||||
vsecp, &acl_ids)) != 0) {
|
||||
vsecp, &acl_ids, mnt_ns)) != 0) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -1237,7 +1243,8 @@ top:
|
||||
return (error);
|
||||
}
|
||||
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr,
|
||||
mnt_ns))) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
zfs_dirent_unlock(dl);
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
@@ -1379,7 +1386,7 @@ top:
|
||||
return (error);
|
||||
}
|
||||
|
||||
if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
|
||||
if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1811,6 +1818,7 @@ next:
|
||||
* flags - ATTR_UTIME set if non-default time values provided.
|
||||
* - ATTR_NOACLCHECK (CIFS context only).
|
||||
* cr - credentials of caller.
|
||||
* mnt_ns - user namespace of the mount
|
||||
*
|
||||
* RETURN: 0 if success
|
||||
* error code if failure
|
||||
@@ -1819,7 +1827,7 @@ next:
|
||||
* ip - ctime updated, mtime updated if size changed.
|
||||
*/
|
||||
int
|
||||
zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
|
||||
zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zuserns_t *mnt_ns)
|
||||
{
|
||||
struct inode *ip;
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(zp);
|
||||
@@ -1968,7 +1976,8 @@ top:
|
||||
*/
|
||||
|
||||
if (mask & ATTR_SIZE) {
|
||||
err = zfs_zaccess(zp, ACE_WRITE_DATA, 0, skipaclchk, cr);
|
||||
err = zfs_zaccess(zp, ACE_WRITE_DATA, 0, skipaclchk, cr,
|
||||
mnt_ns);
|
||||
if (err)
|
||||
goto out3;
|
||||
|
||||
@@ -1993,13 +2002,15 @@ top:
|
||||
XVA_ISSET_REQ(xvap, XAT_CREATETIME) ||
|
||||
XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) {
|
||||
need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0,
|
||||
skipaclchk, cr);
|
||||
skipaclchk, cr, mnt_ns);
|
||||
}
|
||||
|
||||
if (mask & (ATTR_UID|ATTR_GID)) {
|
||||
int idmask = (mask & (ATTR_UID|ATTR_GID));
|
||||
int take_owner;
|
||||
int take_group;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
|
||||
/*
|
||||
* NOTE: even if a new mode is being set,
|
||||
@@ -2013,9 +2024,13 @@ top:
|
||||
* Take ownership or chgrp to group we are a member of
|
||||
*/
|
||||
|
||||
take_owner = (mask & ATTR_UID) && (vap->va_uid == crgetuid(cr));
|
||||
uid = zfs_uid_into_mnt((struct user_namespace *)mnt_ns,
|
||||
vap->va_uid);
|
||||
gid = zfs_gid_into_mnt((struct user_namespace *)mnt_ns,
|
||||
vap->va_gid);
|
||||
take_owner = (mask & ATTR_UID) && (uid == crgetuid(cr));
|
||||
take_group = (mask & ATTR_GID) &&
|
||||
zfs_groupmember(zfsvfs, vap->va_gid, cr);
|
||||
zfs_groupmember(zfsvfs, gid, cr);
|
||||
|
||||
/*
|
||||
* If both ATTR_UID and ATTR_GID are set then take_owner and
|
||||
@@ -2031,7 +2046,7 @@ top:
|
||||
((idmask == ATTR_UID) && take_owner) ||
|
||||
((idmask == ATTR_GID) && take_group)) {
|
||||
if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0,
|
||||
skipaclchk, cr) == 0) {
|
||||
skipaclchk, cr, mnt_ns) == 0) {
|
||||
/*
|
||||
* Remove setuid/setgid for non-privileged users
|
||||
*/
|
||||
@@ -2144,12 +2159,12 @@ top:
|
||||
mutex_exit(&zp->z_lock);
|
||||
|
||||
if (mask & ATTR_MODE) {
|
||||
if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) {
|
||||
if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr,
|
||||
mnt_ns) == 0) {
|
||||
err = secpolicy_setid_setsticky_clear(ip, vap,
|
||||
&oldva, cr);
|
||||
&oldva, cr, mnt_ns);
|
||||
if (err)
|
||||
goto out3;
|
||||
|
||||
trim_mask |= ATTR_MODE;
|
||||
} else {
|
||||
need_policy = TRUE;
|
||||
@@ -2640,6 +2655,7 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
|
||||
* tnm - New entry name.
|
||||
* cr - credentials of caller.
|
||||
* flags - case flags
|
||||
* mnt_ns - user namespace of the mount
|
||||
*
|
||||
* RETURN: 0 on success, error code on failure.
|
||||
*
|
||||
@@ -2648,7 +2664,7 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
|
||||
*/
|
||||
int
|
||||
zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
|
||||
cred_t *cr, int flags)
|
||||
cred_t *cr, int flags, zuserns_t *mnt_ns)
|
||||
{
|
||||
znode_t *szp, *tzp;
|
||||
zfsvfs_t *zfsvfs = ZTOZSB(sdzp);
|
||||
@@ -2841,7 +2857,7 @@ top:
|
||||
* done in a single check.
|
||||
*/
|
||||
|
||||
if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr)))
|
||||
if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr, mnt_ns)))
|
||||
goto out;
|
||||
|
||||
if (S_ISDIR(ZTOI(szp)->i_mode)) {
|
||||
@@ -3008,6 +3024,7 @@ out:
|
||||
* link - Name for new symlink entry.
|
||||
* cr - credentials of caller.
|
||||
* flags - case flags
|
||||
* mnt_ns - user namespace of the mount
|
||||
*
|
||||
* OUT: zpp - Znode for new symbolic link.
|
||||
*
|
||||
@@ -3018,7 +3035,7 @@ out:
|
||||
*/
|
||||
int
|
||||
zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
|
||||
znode_t **zpp, cred_t *cr, int flags)
|
||||
znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns)
|
||||
{
|
||||
znode_t *zp;
|
||||
zfs_dirlock_t *dl;
|
||||
@@ -3056,7 +3073,7 @@ zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
|
||||
}
|
||||
|
||||
if ((error = zfs_acl_ids_create(dzp, 0,
|
||||
vap, cr, NULL, &acl_ids)) != 0) {
|
||||
vap, cr, NULL, &acl_ids, mnt_ns)) != 0) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -3073,7 +3090,7 @@ top:
|
||||
return (error);
|
||||
}
|
||||
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
zfs_dirent_unlock(dl);
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
@@ -3325,7 +3342,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
|
||||
return (SET_ERROR(EPERM));
|
||||
}
|
||||
|
||||
if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr, NULL))) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
@@ -3951,7 +3968,7 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
|
||||
* On Linux we can get here through truncate_range() which
|
||||
* operates directly on inodes, so we need to check access rights.
|
||||
*/
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
|
||||
if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL))) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -1960,7 +1960,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
|
||||
cr, NULL, &acl_ids));
|
||||
cr, NULL, &acl_ids, NULL));
|
||||
zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids);
|
||||
ASSERT3P(zp, ==, rootzp);
|
||||
error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx);
|
||||
|
||||
@@ -371,7 +371,11 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
zpl_vap_init(vap, dip, mode | S_IFDIR, cr);
|
||||
#ifdef HAVE_IOPS_MKDIR_USERNS
|
||||
zpl_vap_init(vap, dip, mode | S_IFDIR, cr, user_ns);
|
||||
#else
|
||||
zpl_vap_init(vap, dip, mode | S_IFDIR, cr, NULL);
|
||||
#endif
|
||||
|
||||
error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0);
|
||||
if (error == 0) {
|
||||
|
||||
@@ -1085,7 +1085,7 @@ zpl_ioctl_setflags(struct file *filp, void __user *arg)
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr);
|
||||
err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, NULL);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
|
||||
@@ -1133,7 +1133,7 @@ zpl_ioctl_setxattr(struct file *filp, void __user *arg)
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr);
|
||||
err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, NULL);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
|
||||
@@ -1221,7 +1221,7 @@ zpl_ioctl_setdosflags(struct file *filp, void __user *arg)
|
||||
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr);
|
||||
err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, NULL);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <sys/zpl.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
|
||||
static struct dentry *
|
||||
zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
{
|
||||
@@ -112,18 +111,22 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
}
|
||||
|
||||
void
|
||||
zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr)
|
||||
zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr,
|
||||
zuserns_t *mnt_ns)
|
||||
{
|
||||
vap->va_mask = ATTR_MODE;
|
||||
vap->va_mode = mode;
|
||||
vap->va_uid = crgetuid(cr);
|
||||
|
||||
vap->va_uid = zfs_uid_from_mnt((struct user_namespace *)mnt_ns,
|
||||
crgetuid(cr));
|
||||
|
||||
if (dir && dir->i_mode & S_ISGID) {
|
||||
vap->va_gid = KGID_TO_SGID(dir->i_gid);
|
||||
if (S_ISDIR(mode))
|
||||
vap->va_mode |= S_ISGID;
|
||||
} else {
|
||||
vap->va_gid = crgetgid(cr);
|
||||
vap->va_gid = zfs_gid_from_mnt((struct user_namespace *)mnt_ns,
|
||||
crgetgid(cr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,14 +143,17 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
|
||||
vattr_t *vap;
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
#ifndef HAVE_IOPS_CREATE_USERNS
|
||||
zuserns_t *user_ns = NULL;
|
||||
#endif
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
zpl_vap_init(vap, dir, mode, cr);
|
||||
zpl_vap_init(vap, dir, mode, cr, user_ns);
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0,
|
||||
mode, &zp, cr, 0, NULL);
|
||||
mode, &zp, cr, 0, NULL, user_ns);
|
||||
if (error == 0) {
|
||||
error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
|
||||
if (error == 0)
|
||||
@@ -184,6 +190,9 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
vattr_t *vap;
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
#ifndef HAVE_IOPS_MKNOD_USERNS
|
||||
zuserns_t *user_ns = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We currently expect Linux to supply rdev=0 for all sockets
|
||||
@@ -194,12 +203,12 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
zpl_vap_init(vap, dir, mode, cr);
|
||||
zpl_vap_init(vap, dir, mode, cr, user_ns);
|
||||
vap->va_rdev = rdev;
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0,
|
||||
mode, &zp, cr, 0, NULL);
|
||||
mode, &zp, cr, 0, NULL, user_ns);
|
||||
if (error == 0) {
|
||||
error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
|
||||
if (error == 0)
|
||||
@@ -236,6 +245,9 @@ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
vattr_t *vap;
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
#ifndef HAVE_TMPFILE_USERNS
|
||||
zuserns_t *userns = NULL;
|
||||
#endif
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
@@ -245,10 +257,10 @@ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
*/
|
||||
if (!IS_POSIXACL(dir))
|
||||
mode &= ~current_umask();
|
||||
zpl_vap_init(vap, dir, mode, cr);
|
||||
zpl_vap_init(vap, dir, mode, cr, userns);
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_tmpfile(dir, vap, 0, mode, &ip, cr, 0, NULL);
|
||||
error = -zfs_tmpfile(dir, vap, 0, mode, &ip, cr, 0, NULL, userns);
|
||||
if (error == 0) {
|
||||
/* d_tmpfile will do drop_nlink, so we should set it first */
|
||||
set_nlink(ip, 1);
|
||||
@@ -311,13 +323,17 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
znode_t *zp;
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
#ifndef HAVE_IOPS_MKDIR_USERNS
|
||||
zuserns_t *user_ns = NULL;
|
||||
#endif
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
zpl_vap_init(vap, dir, mode | S_IFDIR, cr);
|
||||
zpl_vap_init(vap, dir, mode | S_IFDIR, cr, user_ns);
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL);
|
||||
error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL,
|
||||
user_ns);
|
||||
if (error == 0) {
|
||||
error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
|
||||
if (error == 0)
|
||||
@@ -439,7 +455,11 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
|
||||
#ifdef HAVE_SETATTR_PREPARE_USERNS
|
||||
error = zpl_setattr_prepare(user_ns, dentry, ia);
|
||||
#else
|
||||
error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
|
||||
#endif
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
@@ -458,7 +478,11 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
||||
ip->i_atime = zpl_inode_timestamp_truncate(ia->ia_atime, ip);
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_setattr(ITOZ(ip), vap, 0, cr);
|
||||
#ifdef HAVE_SETATTR_PREPARE_USERNS
|
||||
error = -zfs_setattr(ITOZ(ip), vap, 0, cr, user_ns);
|
||||
#else
|
||||
error = -zfs_setattr(ITOZ(ip), vap, 0, cr, NULL);
|
||||
#endif
|
||||
if (!error && (ia->ia_valid & ATTR_MODE))
|
||||
error = zpl_chmod_acl(ip);
|
||||
|
||||
@@ -483,6 +507,9 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
|
||||
cred_t *cr = CRED();
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
#ifndef HAVE_IOPS_RENAME_USERNS
|
||||
zuserns_t *user_ns = NULL;
|
||||
#endif
|
||||
|
||||
/* We don't have renameat2(2) support */
|
||||
if (flags)
|
||||
@@ -491,7 +518,7 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
|
||||
crhold(cr);
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_rename(ITOZ(sdip), dname(sdentry), ITOZ(tdip),
|
||||
dname(tdentry), cr, 0);
|
||||
dname(tdentry), cr, 0, user_ns);
|
||||
spl_fstrans_unmark(cookie);
|
||||
crfree(cr);
|
||||
ASSERT3S(error, <=, 0);
|
||||
@@ -521,14 +548,17 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
|
||||
znode_t *zp;
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
#ifndef HAVE_IOPS_SYMLINK_USERNS
|
||||
zuserns_t *user_ns = NULL;
|
||||
#endif
|
||||
|
||||
crhold(cr);
|
||||
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
|
||||
zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr);
|
||||
zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr, user_ns);
|
||||
|
||||
cookie = spl_fstrans_mark();
|
||||
error = -zfs_symlink(ITOZ(dir), dname(dentry), vap,
|
||||
(char *)name, &zp, cr, 0);
|
||||
(char *)name, &zp, cr, 0, user_ns);
|
||||
if (error == 0) {
|
||||
error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
|
||||
if (error) {
|
||||
|
||||
@@ -374,7 +374,11 @@ const struct super_operations zpl_super_operations = {
|
||||
struct file_system_type zpl_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = ZFS_DRIVER,
|
||||
#if defined(HAVE_IDMAP_MNT_API)
|
||||
.fs_flags = FS_USERNS_MOUNT | FS_ALLOW_IDMAP,
|
||||
#else
|
||||
.fs_flags = FS_USERNS_MOUNT,
|
||||
#endif
|
||||
.mount = zpl_mount,
|
||||
.kill_sb = zpl_kill_sb,
|
||||
};
|
||||
|
||||
@@ -499,7 +499,7 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
|
||||
vap->va_gid = crgetgid(cr);
|
||||
|
||||
error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp,
|
||||
cr, 0, NULL);
|
||||
cr, 0, NULL, NULL);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user