Пример #1
0
int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
		mode_t mode)
{
	struct posix_acl *dfacl, *acl;
	int error = 0;

	dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT);
	if (IS_ERR(dfacl)) {
		error = PTR_ERR(dfacl);
		return (error == -EOPNOTSUPP) ? 0 : error;
	}
	if (!dfacl)
		return 0;
	acl = posix_acl_clone(dfacl, GFP_KERNEL);
	error = -ENOMEM;
	if (!acl)
		goto out_release_dfacl;
	error = posix_acl_create_masq(acl, &mode);
	if (error < 0)
		goto out_release_acl;
	error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ?
						      dfacl : NULL);
out_release_acl:
	posix_acl_release(acl);
out_release_dfacl:
	posix_acl_release(dfacl);
	return error;
}
Пример #2
0
/*
 * Initialize the ACLs of a new inode. If parent directory has default ACL,
 * then clone to new inode. Called from ocfs2_mknod.
 */
int ocfs2_init_acl(handle_t *handle,
		   struct inode *inode,
		   struct inode *dir,
		   struct buffer_head *di_bh,
		   struct buffer_head *dir_bh,
		   struct ocfs2_alloc_context *meta_ac,
		   struct ocfs2_alloc_context *data_ac)
{
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	struct posix_acl *acl = NULL;
	int ret = 0, ret2;
	mode_t mode;

	if (!S_ISLNK(inode->i_mode)) {
		if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
			acl = ocfs2_get_acl_nolock(dir, ACL_TYPE_DEFAULT,
						   dir_bh);
			if (IS_ERR(acl))
				return PTR_ERR(acl);
		}
		if (!acl)
			inode->i_mode &= ~current_umask();
	}
	if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
		struct posix_acl *clone;
		mode_t mode;

		if (S_ISDIR(inode->i_mode)) {
			ret = ocfs2_set_acl(handle, inode, di_bh,
					    ACL_TYPE_DEFAULT, acl,
					    meta_ac, data_ac);
			if (ret)
				goto cleanup;
		}
		clone = posix_acl_clone(acl, GFP_NOFS);
		ret = -ENOMEM;
		if (!clone)
			goto cleanup;

		mode = inode->i_mode;
		ret = posix_acl_create_masq(clone, &mode);
		if (ret >= 0) {
			ret2 = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
			if (ret2) {
				mlog_errno(ret2);
				ret = ret2;
				goto cleanup;
			}
			if (ret > 0) {
				ret = ocfs2_set_acl(handle, inode,
						    di_bh, ACL_TYPE_ACCESS,
						    clone, meta_ac, data_ac);
			}
		}
		posix_acl_release(clone);
	}
cleanup:
	posix_acl_release(acl);
	return ret;
}
Пример #3
0
int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
{
	struct posix_acl *acl, *clone;
	int rc;

	cache_no_acl(inode);

	if (S_ISLNK(*i_mode))
		return 0;	/* Symlink always has no-ACL */

	acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
	if (IS_ERR(acl))
		return PTR_ERR(acl);

	if (!acl) {
		*i_mode &= ~current_umask();
	} else {
		if (S_ISDIR(*i_mode))
			set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);

		clone = posix_acl_clone(acl, GFP_KERNEL);
		if (!clone)
			return -ENOMEM;
		rc = posix_acl_create_masq(clone, (mode_t *)i_mode);
		if (rc < 0) {
			posix_acl_release(clone);
			return rc;
		}
		if (rc > 0)
			set_cached_acl(inode, ACL_TYPE_ACCESS, clone);

		posix_acl_release(clone);
	}
	return 0;
}
Пример #4
0
/**
 * generic_acl_init  -  Take care of acl inheritance at @inode create time
 *
 * Files created inside a directory with a default ACL inherit the
 * directory's default ACL.
 */
int
generic_acl_init(struct inode *inode, struct inode *dir)
{
	struct posix_acl *acl = NULL;
	mode_t mode = inode->i_mode;
	int error;

	inode->i_mode = mode & ~current_umask();
	if (!S_ISLNK(inode->i_mode))
		acl = get_cached_acl(dir, ACL_TYPE_DEFAULT);
	if (acl) {
		struct posix_acl *clone;

		if (S_ISDIR(inode->i_mode))
			set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
		clone = posix_acl_clone(acl, GFP_KERNEL);
		error = -ENOMEM;
		if (!clone)
			goto cleanup;
		error = posix_acl_create_masq(clone, &mode);
		if (error >= 0) {
			inode->i_mode = mode;
			if (error > 0)
				set_cached_acl(inode, ACL_TYPE_ACCESS, clone);
		}
		posix_acl_release(clone);
	}
	error = 0;

cleanup:
	posix_acl_release(acl);
	return error;
}
Пример #5
0
int btrfs_init_acl(struct btrfs_trans_handle *trans,
		   struct inode *inode, struct inode *dir)
{
	struct posix_acl *acl = NULL;
	int ret = 0;

	/* this happens with subvols */
	if (!dir)
		return 0;

	if (!S_ISLNK(inode->i_mode)) {
		if (IS_POSIXACL(dir)) {
			acl = btrfs_get_acl(dir, ACL_TYPE_DEFAULT);
			if (IS_ERR(acl))
				return PTR_ERR(acl);
		}

		if (!acl)
			inode->i_mode &= ~current_umask();
	}

	if (IS_POSIXACL(dir) && acl) {
		struct posix_acl *clone;
		mode_t mode;

		if (S_ISDIR(inode->i_mode)) {
			ret = btrfs_set_acl(trans, inode, acl,
					    ACL_TYPE_DEFAULT);
			if (ret)
				goto failed;
		}
		clone = posix_acl_clone(acl, GFP_NOFS);
		ret = -ENOMEM;
		if (!clone)
			goto failed;

		mode = inode->i_mode;
		ret = posix_acl_create_masq(clone, &mode);
		if (ret >= 0) {
			inode->i_mode = mode;
			if (ret > 0) {
				/* we need an acl */
				ret = btrfs_set_acl(trans, inode, clone,
						    ACL_TYPE_ACCESS);
			}
		}
		posix_acl_release(clone);
	}
failed:
	posix_acl_release(acl);

	return ret;
}
Пример #6
0
int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode)
{
	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
	struct posix_acl *acl, *clone;
	mode_t mode = inode->i_mode;
	int error = 0;

	if (!sdp->sd_args.ar_posix_acl)
		return 0;
	if (S_ISLNK(inode->i_mode))
		return 0;

	acl = gfs2_acl_get(dip, ACL_TYPE_DEFAULT);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (!acl) {
		mode &= ~current_umask();
		if (mode != inode->i_mode)
			error = gfs2_set_mode(inode, mode);
		return error;
	}

	if (S_ISDIR(inode->i_mode)) {
		error = gfs2_acl_set(inode, ACL_TYPE_DEFAULT, acl);
		if (error)
			goto out;
	}

	clone = posix_acl_clone(acl, GFP_NOFS);
	error = -ENOMEM;
	if (!clone)
		goto out;
	posix_acl_release(acl);
	acl = clone;

	error = posix_acl_create_masq(acl, &mode);
	if (error < 0)
		goto out;
	if (error == 0)
		goto munge;

	error = gfs2_acl_set(inode, ACL_TYPE_ACCESS, acl);
	if (error)
		goto out;
munge:
	error = gfs2_set_mode(inode, mode);
out:
	posix_acl_release(acl);
	return error;
}
Пример #7
0
/*
 * Initialize the ACLs of a new inode. Called from ext4_new_inode.
 *
 * dir->i_mutex: down
 * inode->i_mutex: up (access to inode is still exclusive)
 */
int
ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
{
	struct posix_acl *acl = NULL;
	int error = 0;

	if (!S_ISLNK(inode->i_mode)) {
		if (test_opt(dir->i_sb, POSIX_ACL)) {
			acl = ext4_get_acl(dir, ACL_TYPE_DEFAULT);
			if (IS_ERR(acl))
				return PTR_ERR(acl);
		}
		if (!acl)
			inode->i_mode &= ~current_umask();

	}
	if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
		struct posix_acl *clone;
		mode_t mode;

		if (S_ISDIR(inode->i_mode)) {
			error = ext4_set_acl(handle, inode,
					     ACL_TYPE_DEFAULT, acl);
			if (error)
				goto cleanup;
		}
		clone = posix_acl_clone(acl, GFP_NOFS);
		error = -ENOMEM;
		if (!clone)
			goto cleanup;

		mode = inode->i_mode;
		error = posix_acl_create_masq(clone, &mode);
		if (error >= 0) {
			inode->i_mode = mode;
			if (error > 0) {
				/* This is an extended ACL */
				error = ext4_set_acl(handle, inode,
						     ACL_TYPE_ACCESS, clone);
			}
		}
		posix_acl_release(clone);
	}
cleanup:
	posix_acl_release(acl);
	return error;
}
Пример #8
0
int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
{
	struct posix_acl *acl = NULL;
	struct posix_acl *clone;
	mode_t mode;
	int rc = 0;

	if (S_ISLNK(inode->i_mode))
		return 0;

	acl = jfs_get_acl(dir, ACL_TYPE_DEFAULT);
	if (IS_ERR(acl))
		return PTR_ERR(acl);

	if (acl) {
		if (S_ISDIR(inode->i_mode)) {
			rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl);
			if (rc)
				goto cleanup;
		}
		clone = posix_acl_clone(acl, GFP_KERNEL);
		if (!clone) {
			rc = -ENOMEM;
			goto cleanup;
		}
		mode = inode->i_mode;
		rc = posix_acl_create_masq(clone, &mode);
		if (rc >= 0) {
			inode->i_mode = mode;
			if (rc > 0)
				rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS,
						 clone);
		}
		posix_acl_release(clone);
cleanup:
		posix_acl_release(acl);
	} else
		inode->i_mode &= ~current_umask();

	JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
			       inode->i_mode;

	return rc;
}
Пример #9
0
/*
 * No need for i_mutex because the inode is not yet exposed to the VFS.
 */
int
xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl)
{
	struct posix_acl *clone;
	mode_t mode;
	int error = 0, inherit = 0;

	if (S_ISDIR(inode->i_mode)) {
		error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl);
		if (error)
			return error;
	}

	clone = posix_acl_clone(default_acl, GFP_KERNEL);
	if (!clone)
		return -ENOMEM;

	mode = inode->i_mode;
	error = posix_acl_create_masq(clone, &mode);
	if (error < 0)
		goto out_release_clone;

	/*
	 * If posix_acl_create_masq returns a positive value we need to
	 * inherit a permission that can't be represented using the Unix
	 * mode bits and we actually need to set an ACL.
	 */
	if (error > 0)
		inherit = 1;

	error = xfs_set_mode(inode, mode);
	if (error)
		goto out_release_clone;

	if (inherit)
		error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone);

 out_release_clone:
	posix_acl_release(clone);
	return error;
}
Пример #10
0
int f2fs_init_acl(struct inode *inode, struct inode *dir)
{
	struct posix_acl *acl = NULL;
	mode_t mode;
	struct posix_acl *clone;
	struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
	int error = 0;

	if (!S_ISLNK(inode->i_mode)) {
		if (test_opt(sbi, POSIX_ACL)) {
			acl = f2fs_get_acl(dir, ACL_TYPE_DEFAULT);
			if (IS_ERR(acl))
				return PTR_ERR(acl);
		}
		if (!acl)
			inode->i_mode &= ~current_umask();
	}

	if (test_opt(sbi, POSIX_ACL) && acl) {

		if (S_ISDIR(inode->i_mode)) {
			error = f2fs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
			if (error)
				goto cleanup;
		}
		//error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
		clone = posix_acl_clone(acl, GFP_KERNEL);
		error = -ENOMEM;
		if (!clone)
			goto cleanup;
		mode = inode->i_mode;
		error = posix_acl_create_masq(clone, &mode);
		if (error < 0)
			return error;
		if (error > 0)
			error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl);
	}
cleanup:
	posix_acl_release(acl);
	return error;
}
Пример #11
0
/**
 * generic_acl_init  -  Take care of acl inheritance at @inode create time
 * @ops:    Filesystem specific getacl and setacl callbacks
 *
 * Files created inside a directory with a default ACL inherit the
 * directory's default ACL.
 */
int
generic_acl_init(struct inode *inode, struct inode *dir,
         struct generic_acl_operations *ops)
{
    struct posix_acl *acl = NULL;
    mode_t mode = inode->i_mode;
    int error;

    inode->i_mode = mode & ~current->fs->umask;
    if (!S_ISLNK(inode->i_mode))
        acl = ops->getacl(dir, ACL_TYPE_DEFAULT);
    if (acl) {
        struct posix_acl *clone;

        if (S_ISDIR(inode->i_mode)) {
            clone = posix_acl_clone(acl, GFP_KERNEL);
            error = -ENOMEM;
            if (!clone)
                goto cleanup;
            ops->setacl(inode, ACL_TYPE_DEFAULT, clone);
            posix_acl_release(clone);
        }
        clone = posix_acl_clone(acl, GFP_KERNEL);
        error = -ENOMEM;
        if (!clone)
            goto cleanup;
        error = posix_acl_create_masq(clone, &mode);
        if (error >= 0) {
            inode->i_mode = mode;
            if (error > 0)
                ops->setacl(inode, ACL_TYPE_ACCESS, clone);
        }
        posix_acl_release(clone);
    }
    error = 0;

cleanup:
    posix_acl_release(acl);
    return error;
}
Пример #12
0
int v9fs_acl_mode(struct inode *dir, mode_t *modep,
		  struct posix_acl **dpacl, struct posix_acl **pacl)
{
	int retval = 0;
	mode_t mode = *modep;
	struct posix_acl *acl = NULL;

	if (!S_ISLNK(mode)) {
		acl = v9fs_get_cached_acl(dir, ACL_TYPE_DEFAULT);
		if (IS_ERR(acl))
			return PTR_ERR(acl);
		if (!acl)
			mode &= ~current_umask();
	}
	if (acl) {
		struct posix_acl *clone;

		if (S_ISDIR(mode))
			*dpacl = posix_acl_dup(acl);
		clone = posix_acl_clone(acl, GFP_NOFS);
		posix_acl_release(acl);
		if (!clone)
			return -ENOMEM;

		retval = posix_acl_create_masq(clone, &mode);
		if (retval < 0) {
			posix_acl_release(clone);
			goto cleanup;
		}
		if (retval > 0)
			*pacl = clone;
		else
			posix_acl_release(clone);
	}
	*modep  = mode;
	return 0;
cleanup:
	return retval;

}
Пример #13
0
int jffs2_init_acl(struct inode *inode, struct inode *dir)
{
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	struct posix_acl *acl = NULL, *clone;
	mode_t mode;
	int rc = 0;

	f->i_acl_access = JFFS2_ACL_NOT_CACHED;
	f->i_acl_default = JFFS2_ACL_NOT_CACHED;
	if (!S_ISLNK(inode->i_mode)) {
		acl = jffs2_get_acl(dir, ACL_TYPE_DEFAULT);
		if (IS_ERR(acl))
			return PTR_ERR(acl);
		if (!acl)
			inode->i_mode &= ~current->fs->umask;
	}
	if (acl) {
		if (S_ISDIR(inode->i_mode)) {
			rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
			if (rc)
				goto cleanup;
		}
		clone = posix_acl_clone(acl, GFP_KERNEL);
		rc = -ENOMEM;
		if (!clone)
			goto cleanup;
		mode = inode->i_mode;
		rc = posix_acl_create_masq(clone, &mode);
		if (rc >= 0) {
			inode->i_mode = mode;
			if (rc > 0)
				rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
		}
		posix_acl_release(clone);
	}
 cleanup:
	posix_acl_release(acl);
	return rc;
}
Пример #14
0
int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
{
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	struct posix_acl *acl, *clone;
	int rc;

	f->i_acl_default = NULL;
	f->i_acl_access = NULL;

	if (S_ISLNK(*i_mode))
		return 0;	/* Symlink always has no-ACL */

	acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
	if (IS_ERR(acl))
		return PTR_ERR(acl);

	if (!acl) {
		*i_mode &= ~current->fs->umask;
	} else {
		if (S_ISDIR(*i_mode))
			jffs2_iset_acl(inode, &f->i_acl_default, acl);

		clone = posix_acl_clone(acl, GFP_KERNEL);
		if (!clone)
			return -ENOMEM;
		rc = posix_acl_create_masq(clone, (mode_t *)i_mode);
		if (rc < 0) {
			posix_acl_release(clone);
			return rc;
		}
		if (rc > 0)
			jffs2_iset_acl(inode, &f->i_acl_access, clone);

		posix_acl_release(clone);
	}
	return 0;
}
Пример #15
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;
}
Пример #16
0
Файл: acl.c Проект: Goon83/SALB
/*
 * initialize the ACLs of a new inode.
 * This needs to be called from pvfs2_get_custom_inode.
 * Note that for the root of the PVFS2 file system,
 * dir will be NULL! For all others dir will be non-NULL
 * However, inode cannot be NULL!
 * Returns 0 on success and -ve number on failure.
 */
int pvfs2_init_acl(struct inode *inode, struct inode *dir)
{
    struct posix_acl *acl = NULL;
    int error = 0;
    pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);

    if (dir == NULL)
        dir = inode;
    ClearModeFlag(pvfs2_inode);
    if (!S_ISLNK(inode->i_mode))
    {
        if (get_acl_flag(inode) == 1)
        {
            acl = pvfs2_get_acl(dir, ACL_TYPE_DEFAULT);
            if (IS_ERR(acl)) {
                error = PTR_ERR(acl);
                gossip_err("pvfs2_get_acl (default) failed with error %d\n", error);
                return error;
            }
        }
        if (!acl && dir != inode)
        {
            int old_mode = inode->i_mode;
            inode->i_mode &= ~current->fs->umask;
            gossip_debug(GOSSIP_ACL_DEBUG, "inode->i_mode before %o and "
                    "after %o\n", old_mode, inode->i_mode);
            if (old_mode != inode->i_mode)
                SetModeFlag(pvfs2_inode);
        }
    }
    if (get_acl_flag(inode) == 1 && acl)
    {
        struct posix_acl *clone;
        mode_t mode;

        if (S_ISDIR(inode->i_mode)) 
        {
            error = pvfs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
            if (error) {
                gossip_err("pvfs2_set_acl (default) directory failed with "
                        "error %d\n", error);
                ClearModeFlag(pvfs2_inode);
                goto cleanup;
            }
        }
        clone = posix_acl_clone(acl, GFP_KERNEL);
        error = -ENOMEM;
        if (!clone) {
            gossip_err("posix_acl_clone failed with ENOMEM\n");
            ClearModeFlag(pvfs2_inode);
            goto cleanup;
        }
        mode = inode->i_mode;
        error = posix_acl_create_masq(clone, &mode);
        if (error >= 0)
        {
            gossip_debug(GOSSIP_ACL_DEBUG, "posix_acl_create_masq changed mode "
                    "from %o to %o\n", inode->i_mode, mode);
            /*
             * Dont do a needless ->setattr() if mode has not changed 
             */
            if (inode->i_mode != mode)
                SetModeFlag(pvfs2_inode);
            inode->i_mode = mode;
            /* 
             * if this is an ACL that cannot be captured by
             * the mode bits, go for the server! 
             */
            if (error > 0)
            {
                error = pvfs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
                gossip_debug(GOSSIP_ACL_DEBUG, "pvfs2_set_acl (access) returned %d\n", error);
            }
        }
        posix_acl_release(clone);
    }
    /* If mode of the inode was changed, then do a forcible ->setattr */
    if (ModeFlag(pvfs2_inode))
        pvfs2_flush_inode(inode);
cleanup:
    posix_acl_release(acl);
    return error;
}