1 /*
2 Copyright (C) 2000, 2002, 2003 Andreas Gruenbacher <agruen@suse.de>
3
4 This program is free software: you can redistribute it and/or modify it
5 under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation, either version 2.1 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19 #include <errno.h>
20 #include <sys/acl.h>
21 #include <acl/libacl.h>
22 #include <errno.h>
23 #include "libobj.h"
24
25 #ifndef ENOATTR
26 # define ENOATTR ENODATA
27 #endif
28
29 typedef unsigned int permset_t;
30
31 #define ACL_PERM_NONE (0x0000)
32
33 /* object types */
34 struct acl_permset_obj_tag;
35 typedef struct acl_permset_obj_tag acl_permset_obj;
36 struct qualifier_obj_tag;
37 typedef struct qualifier_obj_tag qualifier_obj;
38 struct acl_entry_obj_tag;
39 typedef struct acl_entry_obj_tag acl_entry_obj;
40 struct acl_obj_tag;
41 typedef struct acl_obj_tag acl_obj;
42
43 /* permset_t object */
44 struct __acl_permset_ext {
45 permset_t s_perm;
46 };
47 struct acl_permset_obj_tag {
48 obj_prefix o_prefix;
49 struct __acl_permset_ext i;
50 };
51
52 #define sperm i.s_perm
53 #define oprefix i.o_prefix
54
55 #define permset_obj_equal(s1, s2) \
56 ((s1).sperm == (s2).sperm)
57
58 /* qualifier object */
59 struct __qualifier_ext {
60 id_t q_id;
61 };
62
63 struct qualifier_obj_tag {
64 obj_prefix o_prefix;
65 struct __qualifier_ext i;
66 };
67
68 #define qid i.q_id
69
70 #define qualifier_obj_id(q) \
71 ((q).qid)
72
73 /* acl_entry object */
74 struct __acl_entry {
75 acl_tag_t e_tag;
76 qualifier_obj e_id;
77 acl_permset_obj e_perm;
78 };
79
80 struct __acl_entry_ext {
81 acl_entry_obj *e_prev, *e_next;
82 acl_obj *e_container;
83 struct __acl_entry e_entry;
84 };
85
86 struct acl_entry_obj_tag {
87 obj_prefix o_prefix;
88 struct __acl_entry_ext i;
89 };
90
91 #define econtainer i.e_container
92 #define eprev i.e_prev
93 #define enext i.e_next
94 #define eentry i.e_entry
95 #define etag i.e_entry.e_tag
96 #define eperm i.e_entry.e_perm
97 #define eid i.e_entry.e_id
98
99 #define init_acl_entry_obj(entry) do { \
100 (entry).etag = ACL_UNDEFINED_TAG; \
101 new_obj_p_here(acl_permset, &(entry).eperm); \
102 (entry).eperm.sperm = ACL_PERM_NONE; \
103 new_obj_p_here(qualifier, &(entry).eid); \
104 (entry).eid.qid = ACL_UNDEFINED_ID; \
105 } while(0)
106
107 /* acl object */
108 struct __acl_ext {
109 acl_entry_obj *a_prev, *a_next;
110 acl_entry_obj *a_curr;
111 acl_entry_obj *a_prealloc, *a_prealloc_end;
112 size_t a_used;
113 };
114 struct acl_obj_tag {
115 obj_prefix o_prefix;
116 struct __acl_ext i;
117 };
118
119 #define aprev i.a_prev
120 #define anext i.a_next
121 #define acurr i.a_curr
122 #define aused i.a_used
123 #define aprealloc i.a_prealloc
124 #define aprealloc_end i.a_prealloc_end
125
126 /* external ACL representation */
127 struct __acl {
128 size_t x_size;
129 struct __acl_entry x_entries[0];
130 };
131
132 extern int __acl_reorder_entry_obj_p(acl_entry_obj *acl_entry_obj_p) hidden;
133 extern int __acl_reorder_obj_p(acl_obj *acl_obj_p) hidden;
134
135 extern acl_obj *__acl_init_obj(int count) hidden;
136 extern acl_entry_obj *__acl_create_entry_obj(acl_obj *acl_obj_p) hidden;
137 extern void __acl_free_acl_obj(acl_obj *acl_obj_p) hidden;
138
139 extern char *__acl_to_any_text(acl_t acl, ssize_t *len_p,
140 const char *prefix, char separator,
141 const char *suffix, int options) hidden;
142 extern int __apply_mask_to_mode(mode_t *mode, acl_t acl) hidden;
143
144 #define FOREACH_ACL_ENTRY(entry_obj_p, acl_obj_p) \
145 for( (entry_obj_p) = (acl_obj_p)->anext; \
146 (entry_obj_p) != (acl_entry_obj *)(acl_obj_p); \
147 (entry_obj_p) = (entry_obj_p)->enext )