xref: /qemu/hw/9pfs/9p-posix-acl.c (revision d57b78002cd1a32f8382fc818da3940df69ff81a)
170fc55ebSAneesh Kumar K.V /*
2*d57b7800SWei Liu  * 9p system.posix* xattr callback
370fc55ebSAneesh Kumar K.V  *
470fc55ebSAneesh Kumar K.V  * Copyright IBM, Corp. 2010
570fc55ebSAneesh Kumar K.V  *
670fc55ebSAneesh Kumar K.V  * Authors:
770fc55ebSAneesh Kumar K.V  * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
870fc55ebSAneesh Kumar K.V  *
970fc55ebSAneesh Kumar K.V  * This work is licensed under the terms of the GNU GPL, version 2.  See
1070fc55ebSAneesh Kumar K.V  * the COPYING file in the top-level directory.
1170fc55ebSAneesh Kumar K.V  *
1270fc55ebSAneesh Kumar K.V  */
1370fc55ebSAneesh Kumar K.V 
1470fc55ebSAneesh Kumar K.V #include <sys/types.h>
151de7afc9SPaolo Bonzini #include "qemu/xattr.h"
1670fc55ebSAneesh Kumar K.V #include "virtio-9p.h"
17353ac78dSAneesh Kumar K.V #include "fsdev/file-op-9p.h"
1870fc55ebSAneesh Kumar K.V #include "virtio-9p-xattr.h"
1970fc55ebSAneesh Kumar K.V 
2070fc55ebSAneesh Kumar K.V #define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access"
2170fc55ebSAneesh Kumar K.V #define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default"
2270fc55ebSAneesh Kumar K.V #define ACL_ACCESS "system.posix_acl_access"
2370fc55ebSAneesh Kumar K.V #define ACL_DEFAULT "system.posix_acl_default"
2470fc55ebSAneesh Kumar K.V 
2570fc55ebSAneesh Kumar K.V static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
2670fc55ebSAneesh Kumar K.V                                 const char *name, void *value, size_t size)
2770fc55ebSAneesh Kumar K.V {
284fa4ce71SChen Gang     char *buffer;
294fa4ce71SChen Gang     ssize_t ret;
304fa4ce71SChen Gang 
314fa4ce71SChen Gang     buffer = rpath(ctx, path);
324fa4ce71SChen Gang     ret = lgetxattr(buffer, MAP_ACL_ACCESS, value, size);
334fa4ce71SChen Gang     g_free(buffer);
344fa4ce71SChen Gang     return ret;
3570fc55ebSAneesh Kumar K.V }
3670fc55ebSAneesh Kumar K.V 
3770fc55ebSAneesh Kumar K.V static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
3870fc55ebSAneesh Kumar K.V                                  char *name, void *value, size_t osize)
3970fc55ebSAneesh Kumar K.V {
4070fc55ebSAneesh Kumar K.V     ssize_t len = sizeof(ACL_ACCESS);
4170fc55ebSAneesh Kumar K.V 
4270fc55ebSAneesh Kumar K.V     if (!value) {
4370fc55ebSAneesh Kumar K.V         return len;
4470fc55ebSAneesh Kumar K.V     }
4570fc55ebSAneesh Kumar K.V 
4670fc55ebSAneesh Kumar K.V     if (osize < len) {
4770fc55ebSAneesh Kumar K.V         errno = ERANGE;
4870fc55ebSAneesh Kumar K.V         return -1;
4970fc55ebSAneesh Kumar K.V     }
5070fc55ebSAneesh Kumar K.V 
519238c209SJim Meyering     /* len includes the trailing NUL */
529238c209SJim Meyering     memcpy(value, ACL_ACCESS, len);
5370fc55ebSAneesh Kumar K.V     return 0;
5470fc55ebSAneesh Kumar K.V }
5570fc55ebSAneesh Kumar K.V 
5670fc55ebSAneesh Kumar K.V static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
5770fc55ebSAneesh Kumar K.V                             void *value, size_t size, int flags)
5870fc55ebSAneesh Kumar K.V {
594fa4ce71SChen Gang     char *buffer;
604fa4ce71SChen Gang     int ret;
614fa4ce71SChen Gang 
624fa4ce71SChen Gang     buffer = rpath(ctx, path);
634fa4ce71SChen Gang     ret = lsetxattr(buffer, MAP_ACL_ACCESS, value, size, flags);
644fa4ce71SChen Gang     g_free(buffer);
654fa4ce71SChen Gang     return ret;
6670fc55ebSAneesh Kumar K.V }
6770fc55ebSAneesh Kumar K.V 
6870fc55ebSAneesh Kumar K.V static int mp_pacl_removexattr(FsContext *ctx,
6970fc55ebSAneesh Kumar K.V                                const char *path, const char *name)
7070fc55ebSAneesh Kumar K.V {
7170fc55ebSAneesh Kumar K.V     int ret;
724fa4ce71SChen Gang     char *buffer;
734fa4ce71SChen Gang 
744fa4ce71SChen Gang     buffer = rpath(ctx, path);
754fa4ce71SChen Gang     ret  = lremovexattr(buffer, MAP_ACL_ACCESS);
7670fc55ebSAneesh Kumar K.V     if (ret == -1 && errno == ENODATA) {
7770fc55ebSAneesh Kumar K.V         /*
78a0994761SAneesh Kumar K.V          * We don't get ENODATA error when trying to remove a
7970fc55ebSAneesh Kumar K.V          * posix acl that is not present. So don't throw the error
8070fc55ebSAneesh Kumar K.V          * even in case of mapped security model
8170fc55ebSAneesh Kumar K.V          */
8270fc55ebSAneesh Kumar K.V         errno = 0;
8370fc55ebSAneesh Kumar K.V         ret = 0;
8470fc55ebSAneesh Kumar K.V     }
854fa4ce71SChen Gang     g_free(buffer);
8670fc55ebSAneesh Kumar K.V     return ret;
8770fc55ebSAneesh Kumar K.V }
8870fc55ebSAneesh Kumar K.V 
8970fc55ebSAneesh Kumar K.V static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
9070fc55ebSAneesh Kumar K.V                                 const char *name, void *value, size_t size)
9170fc55ebSAneesh Kumar K.V {
924fa4ce71SChen Gang     char *buffer;
934fa4ce71SChen Gang     ssize_t ret;
944fa4ce71SChen Gang 
954fa4ce71SChen Gang     buffer = rpath(ctx, path);
964fa4ce71SChen Gang     ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size);
974fa4ce71SChen Gang     g_free(buffer);
984fa4ce71SChen Gang     return ret;
9970fc55ebSAneesh Kumar K.V }
10070fc55ebSAneesh Kumar K.V 
10170fc55ebSAneesh Kumar K.V static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
10270fc55ebSAneesh Kumar K.V                                  char *name, void *value, size_t osize)
10370fc55ebSAneesh Kumar K.V {
10470fc55ebSAneesh Kumar K.V     ssize_t len = sizeof(ACL_DEFAULT);
10570fc55ebSAneesh Kumar K.V 
10670fc55ebSAneesh Kumar K.V     if (!value) {
10770fc55ebSAneesh Kumar K.V         return len;
10870fc55ebSAneesh Kumar K.V     }
10970fc55ebSAneesh Kumar K.V 
11070fc55ebSAneesh Kumar K.V     if (osize < len) {
11170fc55ebSAneesh Kumar K.V         errno = ERANGE;
11270fc55ebSAneesh Kumar K.V         return -1;
11370fc55ebSAneesh Kumar K.V     }
11470fc55ebSAneesh Kumar K.V 
1159238c209SJim Meyering     /* len includes the trailing NUL */
1169005c3b3SShannon Zhao     memcpy(value, ACL_DEFAULT, len);
11770fc55ebSAneesh Kumar K.V     return 0;
11870fc55ebSAneesh Kumar K.V }
11970fc55ebSAneesh Kumar K.V 
12070fc55ebSAneesh Kumar K.V static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
12170fc55ebSAneesh Kumar K.V                             void *value, size_t size, int flags)
12270fc55ebSAneesh Kumar K.V {
1234fa4ce71SChen Gang     char *buffer;
1244fa4ce71SChen Gang     int ret;
1254fa4ce71SChen Gang 
1264fa4ce71SChen Gang     buffer = rpath(ctx, path);
1274fa4ce71SChen Gang     ret = lsetxattr(buffer, MAP_ACL_DEFAULT, value, size, flags);
1284fa4ce71SChen Gang     g_free(buffer);
1294fa4ce71SChen Gang     return ret;
13070fc55ebSAneesh Kumar K.V }
13170fc55ebSAneesh Kumar K.V 
13270fc55ebSAneesh Kumar K.V static int mp_dacl_removexattr(FsContext *ctx,
13370fc55ebSAneesh Kumar K.V                                const char *path, const char *name)
13470fc55ebSAneesh Kumar K.V {
135a0994761SAneesh Kumar K.V     int ret;
1364fa4ce71SChen Gang     char *buffer;
1374fa4ce71SChen Gang 
1384fa4ce71SChen Gang     buffer = rpath(ctx, path);
1394fa4ce71SChen Gang     ret  = lremovexattr(buffer, MAP_ACL_DEFAULT);
140a0994761SAneesh Kumar K.V     if (ret == -1 && errno == ENODATA) {
141a0994761SAneesh Kumar K.V         /*
142a0994761SAneesh Kumar K.V          * We don't get ENODATA error when trying to remove a
143a0994761SAneesh Kumar K.V          * posix acl that is not present. So don't throw the error
144a0994761SAneesh Kumar K.V          * even in case of mapped security model
145a0994761SAneesh Kumar K.V          */
146a0994761SAneesh Kumar K.V         errno = 0;
147a0994761SAneesh Kumar K.V         ret = 0;
148a0994761SAneesh Kumar K.V     }
1494fa4ce71SChen Gang     g_free(buffer);
150a0994761SAneesh Kumar K.V     return ret;
15170fc55ebSAneesh Kumar K.V }
15270fc55ebSAneesh Kumar K.V 
15370fc55ebSAneesh Kumar K.V 
15470fc55ebSAneesh Kumar K.V XattrOperations mapped_pacl_xattr = {
15570fc55ebSAneesh Kumar K.V     .name = "system.posix_acl_access",
15670fc55ebSAneesh Kumar K.V     .getxattr = mp_pacl_getxattr,
15770fc55ebSAneesh Kumar K.V     .setxattr = mp_pacl_setxattr,
15870fc55ebSAneesh Kumar K.V     .listxattr = mp_pacl_listxattr,
15970fc55ebSAneesh Kumar K.V     .removexattr = mp_pacl_removexattr,
16070fc55ebSAneesh Kumar K.V };
16170fc55ebSAneesh Kumar K.V 
16270fc55ebSAneesh Kumar K.V XattrOperations mapped_dacl_xattr = {
16370fc55ebSAneesh Kumar K.V     .name = "system.posix_acl_default",
16470fc55ebSAneesh Kumar K.V     .getxattr = mp_dacl_getxattr,
16570fc55ebSAneesh Kumar K.V     .setxattr = mp_dacl_setxattr,
16670fc55ebSAneesh Kumar K.V     .listxattr = mp_dacl_listxattr,
16770fc55ebSAneesh Kumar K.V     .removexattr = mp_dacl_removexattr,
16870fc55ebSAneesh Kumar K.V };
16970fc55ebSAneesh Kumar K.V 
17070fc55ebSAneesh Kumar K.V XattrOperations passthrough_acl_xattr = {
17170fc55ebSAneesh Kumar K.V     .name = "system.posix_acl_",
17270fc55ebSAneesh Kumar K.V     .getxattr = pt_getxattr,
17370fc55ebSAneesh Kumar K.V     .setxattr = pt_setxattr,
17470fc55ebSAneesh Kumar K.V     .listxattr = pt_listxattr,
17570fc55ebSAneesh Kumar K.V     .removexattr = pt_removexattr,
17670fc55ebSAneesh Kumar K.V };
17770fc55ebSAneesh Kumar K.V 
17870fc55ebSAneesh Kumar K.V XattrOperations none_acl_xattr = {
17970fc55ebSAneesh Kumar K.V     .name = "system.posix_acl_",
18070fc55ebSAneesh Kumar K.V     .getxattr = notsup_getxattr,
18170fc55ebSAneesh Kumar K.V     .setxattr = notsup_setxattr,
18270fc55ebSAneesh Kumar K.V     .listxattr = notsup_listxattr,
18370fc55ebSAneesh Kumar K.V     .removexattr = notsup_removexattr,
18470fc55ebSAneesh Kumar K.V };
185