1 #include "include/types.h"
7 #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO)
10 int posix_acl_check(const void *xattr, size_t size)
12 const acl_ea_header *header;
13 if (size < sizeof(*header))
15 header = reinterpret_cast<const acl_ea_header*>(xattr);
16 ceph_le32 expected_version;
17 expected_version = ACL_EA_VERSION;
18 if (header->a_version != expected_version)
21 const acl_ea_entry *entry = header->a_entries;
22 size -= sizeof(*header);
23 if (size % sizeof(*entry))
26 int count = size / sizeof(*entry);
30 int state = ACL_USER_OBJ;
32 for (int i = 0; i < count; ++i) {
33 __u16 tag = entry->e_tag;
36 if (state == ACL_USER_OBJ) {
42 if (state != ACL_USER)
47 if (state == ACL_USER) {
53 if (state != ACL_GROUP)
58 if (state != ACL_GROUP)
63 if (state == ACL_OTHER ||
64 (state == ACL_GROUP && !needs_mask)) {
75 return state == 0 ? count : -1;
78 int posix_acl_equiv_mode(const void *xattr, size_t size, mode_t *mode_p)
80 if (posix_acl_check(xattr, size) < 0)
86 const acl_ea_header *header = reinterpret_cast<const acl_ea_header*>(xattr);
87 const acl_ea_entry *entry = header->a_entries;
88 int count = (size - sizeof(*header)) / sizeof(*entry);
89 for (int i = 0; i < count; ++i) {
90 __u16 tag = entry->e_tag;
91 __u16 perm = entry->e_perm;
94 mode |= (perm & S_IRWXO) << 6;
97 mode |= (perm & S_IRWXO) << 3;
100 mode |= perm & S_IRWXO;
103 mode = (mode & ~S_IRWXG) | ((perm & S_IRWXO) << 3);
115 *mode_p = (*mode_p & ~ACCESSPERMS) | mode;
119 int posix_acl_inherit_mode(bufferptr& acl, mode_t *mode_p)
121 if (posix_acl_check(acl.c_str(), acl.length()) <= 0)
124 acl_ea_entry *group_entry = NULL, *mask_entry = NULL;
125 mode_t mode = *mode_p;
128 acl_ea_header *header = reinterpret_cast<acl_ea_header*>(acl.c_str());
129 acl_ea_entry *entry = header->a_entries;
130 int count = (acl.length() - sizeof(*header)) / sizeof(*entry);
131 for (int i = 0; i < count; ++i) {
132 __u16 tag = entry->e_tag;
133 __u16 perm = entry->e_perm;
136 perm &= (mode >> 6) | ~S_IRWXO;
137 mode &= (perm << 6) | ~S_IRWXU;
138 entry->e_perm = perm;
148 perm &= mode | ~S_IRWXO;
149 mode &= perm | ~S_IRWXO;
150 entry->e_perm = perm;
164 __u16 perm = mask_entry->e_perm;
165 perm &= (mode >> 3) | ~S_IRWXO;
166 mode &= (perm << 3) | ~S_IRWXG;
167 mask_entry->e_perm = perm;
171 __u16 perm = group_entry->e_perm;
172 perm &= (mode >> 3) | ~S_IRWXO;
173 mode &= (perm << 3) | ~S_IRWXG;
174 group_entry->e_perm = perm;
177 *mode_p = (*mode_p & ~ACCESSPERMS) | mode;
181 int posix_acl_access_chmod(bufferptr& acl, mode_t mode)
183 if (posix_acl_check(acl.c_str(), acl.length()) <= 0)
186 acl_ea_entry *group_entry = NULL, *mask_entry = NULL;
188 acl_ea_header *header = reinterpret_cast<acl_ea_header*>(acl.c_str());
189 acl_ea_entry *entry = header->a_entries;
190 int count = (acl.length() - sizeof(*header)) / sizeof(*entry);
191 for (int i = 0; i < count; ++i) {
192 __u16 tag = entry->e_tag;
195 entry->e_perm = (mode & S_IRWXU) >> 6;
204 entry->e_perm = mode & S_IRWXO;
213 mask_entry->e_perm = (mode & S_IRWXG) >> 3;
217 group_entry->e_perm = (mode & S_IRWXG) >> 3;
222 int posix_acl_permits(const bufferptr& acl, uid_t i_uid, gid_t i_gid,
223 const UserPerm& perms, unsigned want)
225 if (posix_acl_check(acl.c_str(), acl.length()) < 0)
228 const acl_ea_header *header = reinterpret_cast<const acl_ea_header*>(acl.c_str());
229 const acl_ea_entry *entry = header->a_entries;
230 const acl_ea_entry *next_entry;
235 int count = (acl.length() - sizeof(*header)) / sizeof(*entry);
236 for (idx = 0; idx < count; ++idx) {
238 perm = entry->e_perm;
241 if (i_uid == perms.uid())
246 if (id == perms.uid())
252 id = (tag == ACL_GROUP_OBJ) ? i_gid : entry->e_id;
253 if (perms.gid_in_groups(id)) {
255 if ((perm & want) == want)
275 next_entry = entry + 1;
276 for (++idx; idx < count; ++idx) {
277 tag = next_entry->e_tag;
278 if (tag == ACL_MASK) {
279 __u16 mask = next_entry->e_perm;
280 if ((perm & mask & want) == want)
287 if ((perm & want) == want)