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 <sys/types.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 char *buffer; 29 ssize_t ret; 30 31 buffer = rpath(ctx, path); 32 ret = lgetxattr(buffer, MAP_ACL_ACCESS, value, size); 33 g_free(buffer); 34 return ret; 35 } 36 37 static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, 38 char *name, void *value, size_t osize) 39 { 40 ssize_t len = sizeof(ACL_ACCESS); 41 42 if (!value) { 43 return len; 44 } 45 46 if (osize < len) { 47 errno = ERANGE; 48 return -1; 49 } 50 51 /* len includes the trailing NUL */ 52 memcpy(value, ACL_ACCESS, len); 53 return 0; 54 } 55 56 static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name, 57 void *value, size_t size, int flags) 58 { 59 char *buffer; 60 int ret; 61 62 buffer = rpath(ctx, path); 63 ret = lsetxattr(buffer, MAP_ACL_ACCESS, value, size, flags); 64 g_free(buffer); 65 return ret; 66 } 67 68 static int mp_pacl_removexattr(FsContext *ctx, 69 const char *path, const char *name) 70 { 71 int ret; 72 char *buffer; 73 74 buffer = rpath(ctx, path); 75 ret = lremovexattr(buffer, MAP_ACL_ACCESS); 76 if (ret == -1 && errno == ENODATA) { 77 /* 78 * We don't get ENODATA error when trying to remove a 79 * posix acl that is not present. So don't throw the error 80 * even in case of mapped security model 81 */ 82 errno = 0; 83 ret = 0; 84 } 85 g_free(buffer); 86 return ret; 87 } 88 89 static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path, 90 const char *name, void *value, size_t size) 91 { 92 char *buffer; 93 ssize_t ret; 94 95 buffer = rpath(ctx, path); 96 ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size); 97 g_free(buffer); 98 return ret; 99 } 100 101 static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, 102 char *name, void *value, size_t osize) 103 { 104 ssize_t len = sizeof(ACL_DEFAULT); 105 106 if (!value) { 107 return len; 108 } 109 110 if (osize < len) { 111 errno = ERANGE; 112 return -1; 113 } 114 115 /* len includes the trailing NUL */ 116 memcpy(value, ACL_DEFAULT, len); 117 return 0; 118 } 119 120 static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name, 121 void *value, size_t size, int flags) 122 { 123 char *buffer; 124 int ret; 125 126 buffer = rpath(ctx, path); 127 ret = lsetxattr(buffer, MAP_ACL_DEFAULT, value, size, flags); 128 g_free(buffer); 129 return ret; 130 } 131 132 static int mp_dacl_removexattr(FsContext *ctx, 133 const char *path, const char *name) 134 { 135 int ret; 136 char *buffer; 137 138 buffer = rpath(ctx, path); 139 ret = lremovexattr(buffer, MAP_ACL_DEFAULT); 140 if (ret == -1 && errno == ENODATA) { 141 /* 142 * We don't get ENODATA error when trying to remove a 143 * posix acl that is not present. So don't throw the error 144 * even in case of mapped security model 145 */ 146 errno = 0; 147 ret = 0; 148 } 149 g_free(buffer); 150 return ret; 151 } 152 153 154 XattrOperations mapped_pacl_xattr = { 155 .name = "system.posix_acl_access", 156 .getxattr = mp_pacl_getxattr, 157 .setxattr = mp_pacl_setxattr, 158 .listxattr = mp_pacl_listxattr, 159 .removexattr = mp_pacl_removexattr, 160 }; 161 162 XattrOperations mapped_dacl_xattr = { 163 .name = "system.posix_acl_default", 164 .getxattr = mp_dacl_getxattr, 165 .setxattr = mp_dacl_setxattr, 166 .listxattr = mp_dacl_listxattr, 167 .removexattr = mp_dacl_removexattr, 168 }; 169 170 XattrOperations passthrough_acl_xattr = { 171 .name = "system.posix_acl_", 172 .getxattr = pt_getxattr, 173 .setxattr = pt_setxattr, 174 .listxattr = pt_listxattr, 175 .removexattr = pt_removexattr, 176 }; 177 178 XattrOperations none_acl_xattr = { 179 .name = "system.posix_acl_", 180 .getxattr = notsup_getxattr, 181 .setxattr = notsup_setxattr, 182 .listxattr = notsup_listxattr, 183 .removexattr = notsup_removexattr, 184 }; 185