static int security_del(struct inode *inode, const char *name)
{
	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
		return -EINVAL;

	if (is_reiserfs_priv_object(inode))
		return -EPERM;

	return 0;
}
static int
security_get(struct inode *inode, const char *name, void *buffer, size_t size)
{
	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
		return -EINVAL;

	if (is_reiserfs_priv_object(inode))
		return -EPERM;

	return reiserfs_xattr_get(inode, name, buffer, size);
}
static int
security_list(struct inode *inode, const char *name, int namelen, char *out)
{
	int len = namelen;

	if (is_reiserfs_priv_object(inode))
		return 0;

	if (out)
		memcpy(out, name, len);

	return len;
}
Exemplo n.º 4
0
static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
				      struct nameidata *nd)
{
	int retval;
	struct inode *inode = NULL;
	struct reiserfs_dir_entry de;
	INITIALIZE_PATH(path_to_entry);

	if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len)
		return ERR_PTR(-ENAMETOOLONG);

	reiserfs_write_lock(dir->i_sb);
	de.de_gen_number_bit_string = NULL;
	retval =
	    reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
				&path_to_entry, &de);
	pathrelse(&path_to_entry);
	if (retval == NAME_FOUND) {
		/* Hide the .reiserfs_priv directory */
		if (reiserfs_xattrs(dir->i_sb) &&
		    !old_format_only(dir->i_sb) &&
		    REISERFS_SB(dir->i_sb)->priv_root &&
		    REISERFS_SB(dir->i_sb)->priv_root->d_inode &&
		    de.de_objectid ==
		    le32_to_cpu(INODE_PKEY
				(REISERFS_SB(dir->i_sb)->priv_root->d_inode)->
				k_objectid)) {
			reiserfs_write_unlock(dir->i_sb);
			return ERR_PTR(-EACCES);
		}

		inode =
		    reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
		if (!inode || IS_ERR(inode)) {
			reiserfs_write_unlock(dir->i_sb);
			return ERR_PTR(-EACCES);
		}

		/* Propogate the priv_object flag so we know we're in the priv tree */
		if (is_reiserfs_priv_object(dir))
			reiserfs_mark_inode_private(inode);
	}
	reiserfs_write_unlock(dir->i_sb);
	if (retval == IO_ERROR) {
		return ERR_PTR(-EIO);
	}

	return d_splice_alias(inode, dentry);
}
Exemplo n.º 5
0
/* Looks up and caches the result of the default ACL.
 * We do this so that we don't need to carry the xattr_sem into
 * reiserfs_new_inode if we don't need to */
int reiserfs_cache_default_acl(struct inode *inode)
{
    int ret = 0;
    if (reiserfs_posixacl(inode->i_sb) && !is_reiserfs_priv_object(inode)) {
        struct posix_acl *acl;
        reiserfs_read_lock_xattr_i(inode);
        reiserfs_read_lock_xattrs(inode->i_sb);
        acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
        reiserfs_read_unlock_xattrs(inode->i_sb);
        reiserfs_read_unlock_xattr_i(inode);
        ret = (acl && !IS_ERR(acl));
        if (ret)
            posix_acl_release(acl);
    }

    return ret;
}
Exemplo n.º 6
0
/* dir->i_sem: down,
 * inode is new and not released into the wild yet */
int
reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode)
{
    struct posix_acl *acl;
    int err = 0;

    /* ACLs only get applied to files and directories */
    if (S_ISLNK (inode->i_mode))
        return 0;

    /* ACLs can only be used on "new" objects, so if it's an old object
     * there is nothing to inherit from */
    if (get_inode_sd_version (dir) == STAT_DATA_V1)
        goto apply_umask;

    /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This
     * would be useless since permissions are ignored, and a pain because
     * it introduces locking cycles */
    if (is_reiserfs_priv_object (dir)) {
        reiserfs_mark_inode_private (inode);
        goto apply_umask;
    }

    acl = reiserfs_get_acl (dir, ACL_TYPE_DEFAULT);
    if (IS_ERR (acl)) {
        if (PTR_ERR (acl) == -ENODATA)
            goto apply_umask;
        return PTR_ERR (acl);
    }

    if (acl) {
        struct posix_acl *acl_copy;
        mode_t mode = inode->i_mode;
        int need_acl;

        /* Copy the default ACL to the default ACL of a new directory */
        if (S_ISDIR (inode->i_mode)) {
            err = reiserfs_set_acl (inode, ACL_TYPE_DEFAULT, acl);
            if (err)
                goto cleanup;
        }

        /* Now we reconcile the new ACL and the mode,
           potentially modifying both */
        acl_copy = posix_acl_clone (acl, GFP_NOFS);
        if (!acl_copy) {
            err = -ENOMEM;
            goto cleanup;
        }


        need_acl = posix_acl_create_masq (acl_copy, &mode);
        if (need_acl >= 0) {
            if (mode != inode->i_mode) {
                inode->i_mode = mode;
            }

            /* If we need an ACL.. */
            if (need_acl > 0) {
                err = reiserfs_set_acl (inode, ACL_TYPE_ACCESS, acl_copy);
                if (err)
                    goto cleanup_copy;
            }
        }
cleanup_copy:
        posix_acl_release (acl_copy);
cleanup:
        posix_acl_release (acl);
    } else {
apply_umask:
        /* no ACL, apply umask */
        inode->i_mode &= ~current->fs->umask;
    }

    return err;
}