Пример #1
0
static int
ext2_xattr_security_set(const struct xattr_handler *handler,
			struct dentry *dentry, const char *name,
			const void *value, size_t size, int flags)
{
	return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name,
			      value, size, flags);
}
static int
ext2_xattr_security_set(struct dentry *dentry, const char *name,
		const void *value, size_t size, int flags, int type)
{
	if (strcmp(name, "") == 0)
		return -EINVAL;
	return ext2_xattr_set(dentry->d_inode, EXT2_XATTR_INDEX_SECURITY, name,
			      value, size, flags);
}
Пример #3
0
static int
ext2_xattr_trusted_set(struct inode *inode, const char *name,
		       const void *value, size_t size, int flags)
{
	if (strcmp(name, "") == 0)
		return -EINVAL;
	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name,
			      value, size, flags);
}
Пример #4
0
void ext2_delete_from_parent(struct inode * inode)
{
  int *value, *new_value, retval, count, *temp, *temp1;
  unsigned long parent_ino;
  struct inode * parent_inode;

  // ext2_debug("%lu: Looking for parent\n", inode->i_ino);
  retval = ext2_xattr_get(inode, 10, "parent", NULL, 0);
  if(retval > 0)
    {
      // ext2_debug("%lu: retval > 0\n", inode->i_ino);
      retval = ext2_xattr_get(inode, 10, "parent", &parent_ino, sizeof(unsigned long));
      // ext2_debug("%lu: Found parent %lu\n", inode->i_ino, parent_ino);
      parent_inode = iget(inode->i_sb, parent_ino);
      if(!parent_inode)
	return;
      retval = ext2_xattr_get(parent_inode, 11, "children", NULL, 0);
      if (retval > 0) {
	value = (int *)kmalloc(retval, GFP_KERNEL);
	new_value = (int *)kmalloc(retval, GFP_KERNEL);
	temp = value;
	temp1 = new_value;
	retval = ext2_xattr_get(parent_inode, 11, "children", value, retval);
	count = 0;
	while(*value)
	  {
	    if(*value != (int)(inode->i_ino))
	      {
		*new_value = *value;
		new_value++;
		count++;
	      }
	    else
	      {
       	        // ext2_debug("%lu: deleting %d from parent list\n", parent_inode->i_ino, *value);
	      }
	    value++;
	  }
	// ext2_debug("%lu: parent has %d children left\n", parent_inode->i_ino, count);
	*new_value = 0;
        ext2_xattr_set(parent_inode, 11, "children", temp1, (count+1)*sizeof(int), 0);
	if(!count)
	  {
	    // delete inode
	  }
      cleanup:
	kfree(temp);
	kfree(temp1);
	iput(parent_inode); /* This should take care of dropping root when it has no children */
      }
    }
  else
    {
      // ext2_debug("no parent found\n");
      return;
    }
}
Пример #5
0
static int
ext2_xattr_trusted_set(const struct xattr_handler *handler,
		       struct dentry *dentry, const char *name,
		       const void *value, size_t size, int flags)
{
	if (strcmp(name, "") == 0)
		return -EINVAL;
	return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name,
			      value, size, flags);
}
Пример #6
0
static int
ext2_xattr_user_set(struct inode *inode, const char *name,
		    const void *value, size_t size, int flags)
{
	if (strcmp(name, "") == 0)
		return -EINVAL;
	if (!test_opt(inode->i_sb, XATTR_USER))
		return -EOPNOTSUPP;

	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
			      value, size, flags);
}
Пример #7
0
/*
 * inode->i_mutex: down
 */
static int
ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
{
	int name_index;
	void *value = NULL;
	size_t size = 0;
	int error;

	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;
	if (!test_opt(inode->i_sb, POSIX_ACL))
		return 0;

	switch(type) {
		case ACL_TYPE_ACCESS:
			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
			if (acl) {
				mode_t mode = inode->i_mode;
				error = posix_acl_equiv_mode(acl, &mode);
				if (error < 0)
					return error;
				else {
					inode->i_mode = mode;
					inode->i_ctime = CURRENT_TIME_SEC;
					mark_inode_dirty(inode);
					if (error == 0)
						acl = NULL;
				}
			}
			break;

		case ACL_TYPE_DEFAULT:
			name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT;
			if (!S_ISDIR(inode->i_mode))
				return acl ? -EACCES : 0;
			break;

		default:
			return -EINVAL;
	}
 	if (acl) {
		value = ext2_acl_to_disk(acl, &size);
		if (IS_ERR(value))
			return (int)PTR_ERR(value);
	}

	error = ext2_xattr_set(inode, name_index, "", value, size, 0);

	kfree(value);
	if (!error)
		set_cached_acl(inode, type, acl);
	return error;
}
Пример #8
0
static int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
			   void *fs_info)
{
	const struct xattr *xattr;
	int err = 0;

	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
		err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
				     xattr->name, xattr->value,
				     xattr->value_len, 0);
		if (err < 0)
			break;
	}
	return err;
}
Пример #9
0
/*
 * inode->i_mutex: down
 */
int
ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
	int name_index;
	void *value = NULL;
	size_t size = 0;
	int error;

	switch(type) {
		case ACL_TYPE_ACCESS:
			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
			if (acl) {
				error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
				if (error)
					return error;
				inode->i_ctime = current_time(inode);
				mark_inode_dirty(inode);
			}
			break;

		case ACL_TYPE_DEFAULT:
			name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT;
			if (!S_ISDIR(inode->i_mode))
				return acl ? -EACCES : 0;
			break;

		default:
			return -EINVAL;
	}
 	if (acl) {
		value = ext2_acl_to_disk(acl, &size);
		if (IS_ERR(value))
			return (int)PTR_ERR(value);
	}

	error = ext2_xattr_set(inode, name_index, "", value, size, 0);

	kfree(value);
	if (!error)
		set_cached_acl(inode, type, acl);
	return error;
}
Пример #10
0
static int
ext2_xattr_user_set(struct inode *inode, const char *name,
		    const void *value, size_t size, int flags)
{
	int error;

	if (strcmp(name, "") == 0)
		return -EINVAL;
	if (!test_opt(inode->i_sb, XATTR_USER))
		return -EOPNOTSUPP;
	if ( !S_ISREG(inode->i_mode) &&
	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
		return -EPERM;
	error = permission(inode, MAY_WRITE, NULL);
	if (error)
		return error;

	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
			      value, size, flags);
}
Пример #11
0
int
ext2_init_security(struct inode *inode, struct inode *dir)
{
	int err;
	size_t len;
	void *value;
	char *name;

	err = security_inode_init_security(inode, dir, &name, &value, &len);
	if (err) {
		if (err == -EOPNOTSUPP)
			return 0;
		return err;
	}
	err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
			     name, value, len, 0);
	kfree(name);
	kfree(value);
	return err;
}
Пример #12
0
/*
 * inode->i_sem: down
 */
static int
ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
{
	struct ext2_inode_info *ei = EXT2_I(inode);
	int name_index;
	void *value = NULL;
	size_t size;
	int error;

	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;
	if (!test_opt(inode->i_sb, POSIX_ACL))
		return 0;

	switch(type) {
		case ACL_TYPE_ACCESS:
			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
			if (acl) {
				mode_t mode = inode->i_mode;
				error = posix_acl_equiv_mode(acl, &mode);
				if (error < 0)
					return error;
				else {
					inode->i_mode = mode;
					mark_inode_dirty(inode);
					if (error == 0)
						acl = NULL;
				}
			}
			break;

		case ACL_TYPE_DEFAULT:
			name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT;
			if (!S_ISDIR(inode->i_mode))
				return acl ? -EACCES : 0;
			break;

		default:
			return -EINVAL;
	}
 	if (acl) {
		if (acl->a_count > EXT2_ACL_MAX_ENTRIES)
			return -EINVAL;
		value = ext2_acl_to_disk(acl, &size);
		if (IS_ERR(value))
			return (int)PTR_ERR(value);
	}

	error = ext2_xattr_set(inode, name_index, "", value, size, 0);

	if (value)
		kfree(value);
	if (!error) {
		switch(type) {
			case ACL_TYPE_ACCESS:
				ext2_iset_acl(inode, &ei->i_acl, acl);
				break;

			case ACL_TYPE_DEFAULT:
				ext2_iset_acl(inode, &ei->i_default_acl, acl);
				break;
		}
	}
	return error;
}