xref: /openbmc/qemu/hw/9pfs/9p-posix-acl.c (revision 84a3a53c)
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