acl.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright (C) 2007 Red Hat. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License v2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public
  14. * License along with this program; if not, write to the
  15. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. * Boston, MA 021110-1307, USA.
  17. */
  18. #include <linux/fs.h>
  19. #include <linux/string.h>
  20. #include <linux/xattr.h>
  21. #include <linux/posix_acl_xattr.h>
  22. #include <linux/sched.h>
  23. #include "ctree.h"
  24. #include "xattr.h"
  25. #ifndef is_owner_or_cap
  26. #define is_owner_or_cap(inode) \
  27. ((current->fsuid == (inode)->i_uid) || capable(CAP_FOWNER))
  28. #endif
  29. static int btrfs_xattr_set_acl(struct inode *inode, int type,
  30. const void *value, size_t size)
  31. {
  32. int ret = 0;
  33. struct posix_acl *acl;
  34. if (!is_owner_or_cap(inode))
  35. return -EPERM;
  36. if (value) {
  37. acl = posix_acl_from_xattr(value, size);
  38. if (acl == NULL) {
  39. value = NULL;
  40. size = 0;
  41. } else if (IS_ERR(acl)) {
  42. ret = PTR_ERR(acl);
  43. } else {
  44. ret = posix_acl_valid(acl);
  45. posix_acl_release(acl);
  46. }
  47. if (ret)
  48. return ret;
  49. }
  50. return btrfs_xattr_set(inode, type, "", value, size, 0);
  51. }
  52. static int btrfs_xattr_get_acl(struct inode *inode, int type,
  53. void *value, size_t size)
  54. {
  55. return btrfs_xattr_get(inode, type, "", value, size);
  56. }
  57. static int btrfs_xattr_acl_access_get(struct inode *inode, const char *name,
  58. void *value, size_t size)
  59. {
  60. if (*name != '\0')
  61. return -EINVAL;
  62. return btrfs_xattr_get_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS,
  63. value, size);
  64. }
  65. static int btrfs_xattr_acl_access_set(struct inode *inode, const char *name,
  66. const void *value, size_t size, int flags)
  67. {
  68. if (*name != '\0')
  69. return -EINVAL;
  70. return btrfs_xattr_set_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_ACCESS,
  71. value, size);
  72. }
  73. static int btrfs_xattr_acl_default_get(struct inode *inode, const char *name,
  74. void *value, size_t size)
  75. {
  76. if (*name != '\0')
  77. return -EINVAL;
  78. return btrfs_xattr_get_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT,
  79. value, size);
  80. }
  81. static int btrfs_xattr_acl_default_set(struct inode *inode, const char *name,
  82. const void *value, size_t size, int flags)
  83. {
  84. if (*name != '\0')
  85. return -EINVAL;
  86. return btrfs_xattr_set_acl(inode, BTRFS_XATTR_INDEX_POSIX_ACL_DEFAULT,
  87. value, size);
  88. }
  89. struct xattr_handler btrfs_xattr_acl_default_handler = {
  90. .prefix = POSIX_ACL_XATTR_DEFAULT,
  91. .list = btrfs_xattr_generic_list,
  92. .get = btrfs_xattr_acl_default_get,
  93. .set = btrfs_xattr_acl_default_set,
  94. };
  95. struct xattr_handler btrfs_xattr_acl_access_handler = {
  96. .prefix = POSIX_ACL_XATTR_ACCESS,
  97. .list = btrfs_xattr_generic_list,
  98. .get = btrfs_xattr_acl_access_get,
  99. .set = btrfs_xattr_acl_access_set,
  100. };