9p-posix-acl.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * 9p system.posix* xattr callback
  3. *
  4. * Copyright IBM, Corp. 2010
  5. *
  6. * Authors:
  7. * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2. See
  10. * the COPYING file in the top-level directory.
  11. *
  12. */
  13. /*
  14. * Not so fast! You might want to read the 9p developer docs first:
  15. * https://wiki.qemu.org/Documentation/9p
  16. */
  17. #include "qemu/osdep.h"
  18. #include "qemu/xattr.h"
  19. #include "9p.h"
  20. #include "fsdev/file-op-9p.h"
  21. #include "9p-xattr.h"
  22. #define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access"
  23. #define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default"
  24. #define ACL_ACCESS "system.posix_acl_access"
  25. #define ACL_DEFAULT "system.posix_acl_default"
  26. static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
  27. const char *name, void *value, size_t size)
  28. {
  29. return local_getxattr_nofollow(ctx, path, MAP_ACL_ACCESS, value, size);
  30. }
  31. static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
  32. char *name, void *value, size_t osize)
  33. {
  34. ssize_t len = sizeof(ACL_ACCESS);
  35. if (!value) {
  36. return len;
  37. }
  38. if (osize < len) {
  39. errno = ERANGE;
  40. return -1;
  41. }
  42. /* len includes the trailing NUL */
  43. memcpy(value, ACL_ACCESS, len);
  44. return 0;
  45. }
  46. static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
  47. void *value, size_t size, int flags)
  48. {
  49. return local_setxattr_nofollow(ctx, path, MAP_ACL_ACCESS, value, size,
  50. flags);
  51. }
  52. static int mp_pacl_removexattr(FsContext *ctx,
  53. const char *path, const char *name)
  54. {
  55. int ret;
  56. ret = local_removexattr_nofollow(ctx, path, MAP_ACL_ACCESS);
  57. /*
  58. * macOS returns ENOATTR (!=ENODATA on macOS), whereas Linux returns
  59. * ENODATA (==ENOATTR on Linux), so checking for ENOATTR is fine
  60. */
  61. if (ret == -1 && errno == ENOATTR) {
  62. /*
  63. * We don't get ENODATA error when trying to remove a
  64. * posix acl that is not present. So don't throw the error
  65. * even in case of mapped security model
  66. */
  67. errno = 0;
  68. ret = 0;
  69. }
  70. return ret;
  71. }
  72. static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
  73. const char *name, void *value, size_t size)
  74. {
  75. return local_getxattr_nofollow(ctx, path, MAP_ACL_DEFAULT, value, size);
  76. }
  77. static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
  78. char *name, void *value, size_t osize)
  79. {
  80. ssize_t len = sizeof(ACL_DEFAULT);
  81. if (!value) {
  82. return len;
  83. }
  84. if (osize < len) {
  85. errno = ERANGE;
  86. return -1;
  87. }
  88. /* len includes the trailing NUL */
  89. memcpy(value, ACL_DEFAULT, len);
  90. return 0;
  91. }
  92. static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
  93. void *value, size_t size, int flags)
  94. {
  95. return local_setxattr_nofollow(ctx, path, MAP_ACL_DEFAULT, value, size,
  96. flags);
  97. }
  98. static int mp_dacl_removexattr(FsContext *ctx,
  99. const char *path, const char *name)
  100. {
  101. int ret;
  102. ret = local_removexattr_nofollow(ctx, path, MAP_ACL_DEFAULT);
  103. /*
  104. * macOS returns ENOATTR (!=ENODATA on macOS), whereas Linux returns
  105. * ENODATA (==ENOATTR on Linux), so checking for ENOATTR is fine
  106. */
  107. if (ret == -1 && errno == ENOATTR) {
  108. /*
  109. * We don't get ENODATA error when trying to remove a
  110. * posix acl that is not present. So don't throw the error
  111. * even in case of mapped security model
  112. */
  113. errno = 0;
  114. ret = 0;
  115. }
  116. return ret;
  117. }
  118. XattrOperations mapped_pacl_xattr = {
  119. .name = "system.posix_acl_access",
  120. .getxattr = mp_pacl_getxattr,
  121. .setxattr = mp_pacl_setxattr,
  122. .listxattr = mp_pacl_listxattr,
  123. .removexattr = mp_pacl_removexattr,
  124. };
  125. XattrOperations mapped_dacl_xattr = {
  126. .name = "system.posix_acl_default",
  127. .getxattr = mp_dacl_getxattr,
  128. .setxattr = mp_dacl_setxattr,
  129. .listxattr = mp_dacl_listxattr,
  130. .removexattr = mp_dacl_removexattr,
  131. };
  132. XattrOperations passthrough_acl_xattr = {
  133. .name = "system.posix_acl_",
  134. .getxattr = pt_getxattr,
  135. .setxattr = pt_setxattr,
  136. .listxattr = pt_listxattr,
  137. .removexattr = pt_removexattr,
  138. };
  139. XattrOperations none_acl_xattr = {
  140. .name = "system.posix_acl_",
  141. .getxattr = notsup_getxattr,
  142. .setxattr = notsup_setxattr,
  143. .listxattr = notsup_listxattr,
  144. .removexattr = notsup_removexattr,
  145. };