1 #include "include/compat.h"
2 #include "include/types.h"
3 #include "include/fs_types.h"
8 int posix_acl_check(const void *xattr
, size_t size
)
10 const acl_ea_header
*header
;
11 if (size
< sizeof(*header
))
13 header
= reinterpret_cast<const acl_ea_header
*>(xattr
);
14 ceph_le32 expected_version
;
15 expected_version
= ACL_EA_VERSION
;
16 if (header
->a_version
!= expected_version
)
19 const acl_ea_entry
*entry
= header
->a_entries
;
20 size
-= sizeof(*header
);
21 if (size
% sizeof(*entry
))
24 int count
= size
/ sizeof(*entry
);
28 int state
= ACL_USER_OBJ
;
30 for (int i
= 0; i
< count
; ++i
) {
31 __u16 tag
= entry
->e_tag
;
34 if (state
== ACL_USER_OBJ
) {
40 if (state
!= ACL_USER
)
45 if (state
== ACL_USER
) {
51 if (state
!= ACL_GROUP
)
56 if (state
!= ACL_GROUP
)
61 if (state
== ACL_OTHER
||
62 (state
== ACL_GROUP
&& !needs_mask
)) {
73 return state
== 0 ? count
: -1;
76 int posix_acl_equiv_mode(const void *xattr
, size_t size
, mode_t
*mode_p
)
78 if (posix_acl_check(xattr
, size
) < 0)
79 return -CEPHFS_EINVAL
;
84 const acl_ea_header
*header
= reinterpret_cast<const acl_ea_header
*>(xattr
);
85 const acl_ea_entry
*entry
= header
->a_entries
;
86 int count
= (size
- sizeof(*header
)) / sizeof(*entry
);
87 for (int i
= 0; i
< count
; ++i
) {
88 __u16 tag
= entry
->e_tag
;
89 __u16 perm
= entry
->e_perm
;
92 mode
|= (perm
& S_IRWXO
) << 6;
95 mode
|= (perm
& S_IRWXO
) << 3;
98 mode
|= perm
& S_IRWXO
;
101 mode
= (mode
& ~S_IRWXG
) | ((perm
& S_IRWXO
) << 3);
108 return -CEPHFS_EINVAL
;
113 *mode_p
= (*mode_p
& ~ACCESSPERMS
) | mode
;
117 int posix_acl_inherit_mode(bufferptr
& acl
, mode_t
*mode_p
)
119 if (posix_acl_check(acl
.c_str(), acl
.length()) <= 0)
122 acl_ea_entry
*group_entry
= NULL
, *mask_entry
= NULL
;
123 mode_t mode
= *mode_p
;
126 acl_ea_header
*header
= reinterpret_cast<acl_ea_header
*>(acl
.c_str());
127 acl_ea_entry
*entry
= header
->a_entries
;
128 int count
= (acl
.length() - sizeof(*header
)) / sizeof(*entry
);
129 for (int i
= 0; i
< count
; ++i
) {
130 __u16 tag
= entry
->e_tag
;
131 __u16 perm
= entry
->e_perm
;
134 perm
&= (mode
>> 6) | ~S_IRWXO
;
135 mode
&= (perm
<< 6) | ~S_IRWXU
;
136 entry
->e_perm
= perm
;
146 perm
&= mode
| ~S_IRWXO
;
147 mode
&= perm
| ~S_IRWXO
;
148 entry
->e_perm
= perm
;
162 __u16 perm
= mask_entry
->e_perm
;
163 perm
&= (mode
>> 3) | ~S_IRWXO
;
164 mode
&= (perm
<< 3) | ~S_IRWXG
;
165 mask_entry
->e_perm
= perm
;
169 __u16 perm
= group_entry
->e_perm
;
170 perm
&= (mode
>> 3) | ~S_IRWXO
;
171 mode
&= (perm
<< 3) | ~S_IRWXG
;
172 group_entry
->e_perm
= perm
;
175 *mode_p
= (*mode_p
& ~ACCESSPERMS
) | mode
;
179 int posix_acl_access_chmod(bufferptr
& acl
, mode_t mode
)
181 if (posix_acl_check(acl
.c_str(), acl
.length()) <= 0)
184 acl_ea_entry
*group_entry
= NULL
, *mask_entry
= NULL
;
186 acl_ea_header
*header
= reinterpret_cast<acl_ea_header
*>(acl
.c_str());
187 acl_ea_entry
*entry
= header
->a_entries
;
188 int count
= (acl
.length() - sizeof(*header
)) / sizeof(*entry
);
189 for (int i
= 0; i
< count
; ++i
) {
190 __u16 tag
= entry
->e_tag
;
193 entry
->e_perm
= (mode
& S_IRWXU
) >> 6;
202 entry
->e_perm
= mode
& S_IRWXO
;
211 mask_entry
->e_perm
= (mode
& S_IRWXG
) >> 3;
215 group_entry
->e_perm
= (mode
& S_IRWXG
) >> 3;
220 int posix_acl_permits(const bufferptr
& acl
, uid_t i_uid
, gid_t i_gid
,
221 const UserPerm
& perms
, unsigned want
)
223 if (posix_acl_check(acl
.c_str(), acl
.length()) < 0)
226 const acl_ea_header
*header
= reinterpret_cast<const acl_ea_header
*>(acl
.c_str());
227 const acl_ea_entry
*entry
= header
->a_entries
;
228 const acl_ea_entry
*next_entry
;
233 int count
= (acl
.length() - sizeof(*header
)) / sizeof(*entry
);
234 for (idx
= 0; idx
< count
; ++idx
) {
236 perm
= entry
->e_perm
;
239 if (i_uid
== perms
.uid())
244 if (id
== perms
.uid())
250 id
= (tag
== ACL_GROUP_OBJ
) ? i_gid
: entry
->e_id
;
251 if (perms
.gid_in_groups(id
)) {
253 if ((perm
& want
) == want
)
261 return -CEPHFS_EACCES
;
273 next_entry
= entry
+ 1;
274 for (++idx
; idx
< count
; ++idx
) {
275 tag
= next_entry
->e_tag
;
276 if (tag
== ACL_MASK
) {
277 __u16 mask
= next_entry
->e_perm
;
278 if ((perm
& mask
& want
) == want
)
280 return -CEPHFS_EACCES
;
285 if ((perm
& want
) == want
)
287 return -CEPHFS_EACCES
;