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 /* 15 * Not so fast! You might want to read the 9p developer docs first: 16 * https://wiki.qemu.org/Documentation/9p 17 */ 18 19 #include "qemu/osdep.h" 20 #include "qemu/xattr.h" 21 #include "9p.h" 22 #include "fsdev/file-op-9p.h" 23 #include "9p-xattr.h" 24 25 #define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access" 26 #define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default" 27 #define ACL_ACCESS "system.posix_acl_access" 28 #define ACL_DEFAULT "system.posix_acl_default" 29 30 static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path, 31 const char *name, void *value, size_t size) 32 { 33 return local_getxattr_nofollow(ctx, path, MAP_ACL_ACCESS, value, size); 34 } 35 36 static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, 37 char *name, void *value, size_t osize) 38 { 39 ssize_t len = sizeof(ACL_ACCESS); 40 41 if (!value) { 42 return len; 43 } 44 45 if (osize < len) { 46 errno = ERANGE; 47 return -1; 48 } 49 50 /* len includes the trailing NUL */ 51 memcpy(value, ACL_ACCESS, len); 52 return 0; 53 } 54 55 static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name, 56 void *value, size_t size, int flags) 57 { 58 return local_setxattr_nofollow(ctx, path, MAP_ACL_ACCESS, value, size, 59 flags); 60 } 61 62 static int mp_pacl_removexattr(FsContext *ctx, 63 const char *path, const char *name) 64 { 65 int ret; 66 67 ret = local_removexattr_nofollow(ctx, path, MAP_ACL_ACCESS); 68 if (ret == -1 && errno == ENODATA) { 69 /* 70 * We don't get ENODATA error when trying to remove a 71 * posix acl that is not present. So don't throw the error 72 * even in case of mapped security model 73 */ 74 errno = 0; 75 ret = 0; 76 } 77 return ret; 78 } 79 80 static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path, 81 const char *name, void *value, size_t size) 82 { 83 return local_getxattr_nofollow(ctx, path, MAP_ACL_DEFAULT, value, size); 84 } 85 86 static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, 87 char *name, void *value, size_t osize) 88 { 89 ssize_t len = sizeof(ACL_DEFAULT); 90 91 if (!value) { 92 return len; 93 } 94 95 if (osize < len) { 96 errno = ERANGE; 97 return -1; 98 } 99 100 /* len includes the trailing NUL */ 101 memcpy(value, ACL_DEFAULT, len); 102 return 0; 103 } 104 105 static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name, 106 void *value, size_t size, int flags) 107 { 108 return local_setxattr_nofollow(ctx, path, MAP_ACL_DEFAULT, value, size, 109 flags); 110 } 111 112 static int mp_dacl_removexattr(FsContext *ctx, 113 const char *path, const char *name) 114 { 115 int ret; 116 117 ret = local_removexattr_nofollow(ctx, path, MAP_ACL_DEFAULT); 118 if (ret == -1 && errno == ENODATA) { 119 /* 120 * We don't get ENODATA error when trying to remove a 121 * posix acl that is not present. So don't throw the error 122 * even in case of mapped security model 123 */ 124 errno = 0; 125 ret = 0; 126 } 127 return ret; 128 } 129 130 131 XattrOperations mapped_pacl_xattr = { 132 .name = "system.posix_acl_access", 133 .getxattr = mp_pacl_getxattr, 134 .setxattr = mp_pacl_setxattr, 135 .listxattr = mp_pacl_listxattr, 136 .removexattr = mp_pacl_removexattr, 137 }; 138 139 XattrOperations mapped_dacl_xattr = { 140 .name = "system.posix_acl_default", 141 .getxattr = mp_dacl_getxattr, 142 .setxattr = mp_dacl_setxattr, 143 .listxattr = mp_dacl_listxattr, 144 .removexattr = mp_dacl_removexattr, 145 }; 146 147 XattrOperations passthrough_acl_xattr = { 148 .name = "system.posix_acl_", 149 .getxattr = pt_getxattr, 150 .setxattr = pt_setxattr, 151 .listxattr = pt_listxattr, 152 .removexattr = pt_removexattr, 153 }; 154 155 XattrOperations none_acl_xattr = { 156 .name = "system.posix_acl_", 157 .getxattr = notsup_getxattr, 158 .setxattr = notsup_setxattr, 159 .listxattr = notsup_listxattr, 160 .removexattr = notsup_removexattr, 161 }; 162