Exemplo n.º 1
0
STATIC int
linvfs_removexattr(
	struct dentry	*dentry,
	const char	*name)
{
	int		error;
	int		xflags = 0;
	char		*p = (char *)name;
	struct inode	*inode = dentry->d_inode;
	vnode_t		*vp = LINVFS_GET_VP(inode);

	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
		error = -ENOATTR;
		p += xfs_namespaces[SYSTEM_NAMES].namelen;
		if (strcmp(p, POSIXACL_ACCESS) == 0)
			error = xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
		else if (strcmp(p, POSIXACL_DEFAULT) == 0)
			error = xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
		else if (strcmp(p, POSIXCAP) == 0)
			error = xfs_cap_vremove(vp);
		return error;
	}

	if (strncmp(name, xfs_namespaces[ROOT_NAMES].name,
			xfs_namespaces[ROOT_NAMES].namelen) == 0) {
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
		xflags |= ATTR_ROOT;
		p += xfs_namespaces[ROOT_NAMES].namelen;
		VOP_ATTR_REMOVE(vp, p, xflags, NULL, error);
		return -error;
	}
	if (strncmp(name, xfs_namespaces[USER_NAMES].name,
			xfs_namespaces[USER_NAMES].namelen) == 0) {
		p += xfs_namespaces[USER_NAMES].namelen;
		if (!capable_user_xattr(inode))
			return -EPERM;
		VOP_ATTR_REMOVE(vp, p, xflags, NULL, error);
		return -error;
	}
	return -ENOATTR;
}
int
xfs_cap_vremove(
	vnode_t		*vp)
{
	int		error;

	VN_HOLD(vp);
	error = xfs_cap_allow_set(vp);
	if (!error) {
		VOP_ATTR_REMOVE(vp, SGI_CAP_LINUX, ATTR_ROOT, sys_cred, error);
		if (error == ENOATTR)
			error = 0;	/* 'scool */
	}
	VN_RELE(vp);
	return -error;
}
Exemplo n.º 3
0
STATIC int
xfs_attrmulti_attr_remove(
	struct vnode		*vp,
	char			*name,
	__uint32_t		flags)
{
	int			error;


	if (IS_RDONLY(&vp->v_inode))
		return -EROFS;
	if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
		return EPERM;

	VOP_ATTR_REMOVE(vp, name, flags, NULL, error);
	return error;
}
Exemplo n.º 4
0
int
xfs_acl_vremove(
	vnode_t		*vp,
	int		kind)
{
	int		error;

	VN_HOLD(vp);
	error = xfs_acl_allow_set(vp, kind);
	if (!error) {
		VOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT?
				SGI_ACL_DEFAULT: SGI_ACL_FILE,
				ATTR_ROOT, sys_cred, error);
		if (error == ENOATTR)
			error = 0;	/* 'scool */
	}
	VN_RELE(vp);
	return -error;
}
Exemplo n.º 5
0
STATIC int
xfs_attrmulti_by_handle(
	xfs_mount_t		*mp,
	unsigned long		arg,
	struct file		*parfilp,
	struct inode		*parinode)
{
	int			error;
	xfs_attr_multiop_t	*ops;
	xfs_fsop_attrmulti_handlereq_t am_hreq;
	struct inode		*inode;
	vnode_t			*vp;
	unsigned int		i, size;

	error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg,
					sizeof(xfs_fsop_attrmulti_handlereq_t),
					(xfs_fsop_handlereq_t *)&am_hreq,
					&vp, &inode);
	if (error)
		return -error;

	size = am_hreq.opcount * sizeof(attr_multiop_t);
	if (!size || size > 16 * PAGE_SIZE) {
		VN_RELE(vp);
		return -XFS_ERROR(E2BIG);
	}

	ops = (xfs_attr_multiop_t *)kmalloc(size, GFP_KERNEL);
	if (!ops) {
		VN_RELE(vp);
		return -XFS_ERROR(ENOMEM);
	}

	if (copy_from_user(ops, am_hreq.ops, size)) {
		kfree(ops);
		VN_RELE(vp);
		return -XFS_ERROR(EFAULT);
	}

	for (i = 0; i < am_hreq.opcount; i++) {
		switch(ops[i].am_opcode) {
		case ATTR_OP_GET:
			VOP_ATTR_GET(vp,ops[i].am_attrname, ops[i].am_attrvalue,
					&ops[i].am_length, ops[i].am_flags,
					NULL, ops[i].am_error);
			break;
		case ATTR_OP_SET:
			if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
				ops[i].am_error = EPERM;
				break;
			}
			VOP_ATTR_SET(vp,ops[i].am_attrname, ops[i].am_attrvalue,
					ops[i].am_length, ops[i].am_flags,
					NULL, ops[i].am_error);
			break;
		case ATTR_OP_REMOVE:
			if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
				ops[i].am_error = EPERM;
				break;
			}
			VOP_ATTR_REMOVE(vp, ops[i].am_attrname, ops[i].am_flags,
					NULL, ops[i].am_error);
			break;
		default:
			ops[i].am_error = EINVAL;
		}
	}

	if (copy_to_user(am_hreq.ops, ops, size))
		error = -XFS_ERROR(EFAULT);

	kfree(ops);
	VN_RELE(vp);
	return error;
}