X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fext3%2Facl.c;h=926af622c53b9bf29af8af20f26b1487f3791e96;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=a3cf77de0e43bb8618bee56fbb04d9a10a6da24a;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index a3cf77de0..926af622c 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -259,8 +259,6 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, return -EINVAL; } if (acl) { - if (acl->a_count > EXT3_ACL_MAX_ENTRIES) - return -EINVAL; value = ext3_acl_to_disk(acl, &size); if (IS_ERR(value)) return (int)PTR_ERR(value); @@ -285,60 +283,24 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, return error; } -/* - * Inode operation permission(). - * - * inode->i_sem: don't care - */ -int -ext3_permission(struct inode *inode, int mask, struct nameidata *nd) +static int +ext3_check_acl(struct inode *inode, int mask) { - int mode = inode->i_mode; - - /* Nobody gets write access to a read-only fs */ - if ((mask & MAY_WRITE) && IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; - /* Nobody gets write access to an immutable file */ - if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) - return -EACCES; - if (current->fsuid == inode->i_uid) { - mode >>= 6; - } else if (test_opt(inode->i_sb, POSIX_ACL)) { - struct posix_acl *acl; - - /* The access ACL cannot grant access if the group class - permission bits don't contain all requested permissions. */ - if (((mode >> 3) & mask & S_IRWXO) != mask) - goto check_groups; - acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - if (error == -EACCES) - goto check_capabilities; - return error; - } else - goto check_groups; - } else { -check_groups: - if (in_group_p(inode->i_gid)) - mode >>= 3; + struct posix_acl *acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); + + if (acl) { + int error = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); + return error; } - if ((mode & mask & S_IRWXO) == mask) - return 0; -check_capabilities: - /* Allowed to override Discretionary Access Control? */ - if (!(mask & MAY_EXEC) || - (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode)) - if (capable(CAP_DAC_OVERRIDE)) - return 0; - /* Read and search granted if capable(CAP_DAC_READ_SEARCH) */ - if (capable(CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) || - (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))) - return 0; - return -EACCES; + return -EAGAIN; +} + +int +ext3_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + return generic_permission(inode, mask, ext3_check_acl); } /* @@ -452,27 +414,27 @@ out: * Extended attribute handlers */ static size_t -ext3_xattr_list_acl_access(char *list, struct inode *inode, - const char *name, int name_len) +ext3_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len, + const char *name, size_t name_len) { const size_t size = sizeof(XATTR_NAME_ACL_ACCESS); if (!test_opt(inode->i_sb, POSIX_ACL)) return 0; - if (list) + if (list && size <= list_len) memcpy(list, XATTR_NAME_ACL_ACCESS, size); return size; } static size_t -ext3_xattr_list_acl_default(char *list, struct inode *inode, - const char *name, int name_len) +ext3_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len, + const char *name, size_t name_len) { const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT); if (!test_opt(inode->i_sb, POSIX_ACL)) return 0; - if (list) + if (list && size <= list_len) memcpy(list, XATTR_NAME_ACL_DEFAULT, size); return size; } @@ -572,45 +534,16 @@ ext3_xattr_set_acl_default(struct inode *inode, const char *name, return ext3_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); } -struct ext3_xattr_handler ext3_xattr_acl_access_handler = { +struct xattr_handler ext3_xattr_acl_access_handler = { .prefix = XATTR_NAME_ACL_ACCESS, .list = ext3_xattr_list_acl_access, .get = ext3_xattr_get_acl_access, .set = ext3_xattr_set_acl_access, }; -struct ext3_xattr_handler ext3_xattr_acl_default_handler = { +struct xattr_handler ext3_xattr_acl_default_handler = { .prefix = XATTR_NAME_ACL_DEFAULT, .list = ext3_xattr_list_acl_default, .get = ext3_xattr_get_acl_default, .set = ext3_xattr_set_acl_default, }; - -void -exit_ext3_acl(void) -{ - ext3_xattr_unregister(EXT3_XATTR_INDEX_POSIX_ACL_ACCESS, - &ext3_xattr_acl_access_handler); - ext3_xattr_unregister(EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT, - &ext3_xattr_acl_default_handler); -} - -int __init -init_ext3_acl(void) -{ - int error; - - error = ext3_xattr_register(EXT3_XATTR_INDEX_POSIX_ACL_ACCESS, - &ext3_xattr_acl_access_handler); - if (error) - goto fail; - error = ext3_xattr_register(EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT, - &ext3_xattr_acl_default_handler); - if (error) - goto fail; - return 0; - -fail: - exit_ext3_acl(); - return error; -}