/* * FUSE: Filesystem in Userspace * Copyright (C) 2016 Canonical Ltd. <seth.forshee@canonical.com> * * This program can be distributed under the terms of the GNU GPL. * See the file COPYING.
*/
staticinlinebool fuse_no_acl(conststruct fuse_conn *fc, conststruct inode *inode)
{ /* * Refuse interacting with POSIX ACLs for daemons that * don't support FUSE_POSIX_ACL and are not mounted on * the host to retain backwards compatibility.
*/ return !fc->posix_acl && (i_user_ns(inode) != &init_user_ns);
}
/* * FUSE daemons before FUSE_POSIX_ACL was introduced could get and set * POSIX ACLs without them being used for permission checking by the * vfs. Retain that behavior for backwards compatibility as there are * filesystems that do all permission checking for acls in the daemon * and not in the kernel.
*/ if (!fc->posix_acl) return NULL; return __fuse_get_acl(fc, inode, type, rcu);
}
int fuse_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, struct posix_acl *acl, int type)
{ struct inode *inode = d_inode(dentry); struct fuse_conn *fc = get_fuse_conn(inode); constchar *name; int ret;
if (fuse_is_bad(inode)) return -EIO;
if (fc->no_setxattr || fuse_no_acl(fc, inode)) return -EOPNOTSUPP;
if (type == ACL_TYPE_ACCESS)
name = XATTR_NAME_POSIX_ACL_ACCESS; elseif (type == ACL_TYPE_DEFAULT)
name = XATTR_NAME_POSIX_ACL_DEFAULT; else return -EINVAL;
if (acl) { unsignedint extra_flags = 0; /* * Fuse userspace is responsible for updating access * permissions in the inode, if needed. fuse_setxattr * invalidates the inode attributes, which will force * them to be refreshed the next time they are used, * and it also updates i_ctime.
*/
size_t size = posix_acl_xattr_size(acl->a_count); void *value;
if (size > PAGE_SIZE) return -E2BIG;
value = kmalloc(size, GFP_KERNEL); if (!value) return -ENOMEM;
ret = posix_acl_to_xattr(fc->user_ns, acl, value, size); if (ret < 0) {
kfree(value); return ret;
}
/* * Fuse daemons without FUSE_POSIX_ACL never changed the passed * through POSIX ACLs. Such daemons don't expect setgid bits to * be stripped.
*/ if (fc->posix_acl &&
!in_group_or_capable(idmap, inode,
i_gid_into_vfsgid(idmap, inode)))
extra_flags |= FUSE_SETXATTR_ACL_KILL_SGID;
ret = fuse_setxattr(inode, name, value, size, 0, extra_flags);
kfree(value);
} else {
ret = fuse_removexattr(inode, name);
}
if (fc->posix_acl) { /* * Fuse daemons without FUSE_POSIX_ACL never cached POSIX ACLs * and didn't invalidate attributes. Retain that behavior.
*/
forget_all_cached_acls(inode);
fuse_invalidate_attr(inode);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.