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