1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "acl.h"
34
35 ACLFile* load_acl_file(
char *file) {
36 FILE *in = fopen(file,
"r");
37 if(in ==
NULL) {
38 return NULL;
39 }
40
41 ACLFile *conf = malloc(
sizeof(ACLFile));
42 conf->parser.parse = acl_parse;
43 conf->namedACLs =
NULL;
44 conf->uriACLs =
NULL;
45 conf->pathACLs =
NULL;
46
47 int r = cfg_parse_basic_file((ConfigParser*)conf, in);
48 if(r !=
0) {
49 free_acl_file(conf);
50 return NULL;
51 }
52
53 fclose(in);
54
55 return conf;
56 }
57
58 void free_acl_file(ACLFile *conf) {
59 ucx_mempool_destroy(conf->parser.mp->pool);
60 free(conf);
61 }
62
63 int acl_parse(
void *p, ConfigLine *begin, ConfigLine *end,
sstr_t line) {
64 ACLFile *aclf = p;
65 UcxAllocator *mp = aclf->parser.mp;
66
67 if(sstrprefix(line, sstr(
"ACL "))) {
68 sstr_t param = sstrsubs(line,
4);
69 UcxList *plist = cfg_param_list(param, mp);
70 ACLConfig *acl =
OBJ_NEW(mp, ACLConfig);
71 acl->type.ptr =
NULL;
72 acl->authparam =
NULL;
73 acl->entries =
NULL;
74 aclf->cur = acl;
75
76 sstr_t type = cfg_param_get(plist, sstr(
"type"));
77 sstr_t name = cfg_param_get(plist, sstr(
"name"));
78 sstr_t path = cfg_param_get(plist, sstr(
"path"));
79 sstr_t uri = cfg_param_get(plist, sstr(
"uri"));
80
81 if(name.ptr) {
82 acl->id = name;
83 aclf->namedACLs = ucx_list_append_a(mp, aclf->namedACLs, acl);
84 }
else if(path.ptr) {
85 acl->id = path;
86 aclf->pathACLs = ucx_list_append_a(mp, aclf->pathACLs, acl);
87 }
else if(uri.ptr) {
88 acl->id = uri;
89 aclf->uriACLs = ucx_list_append_a(mp, aclf->uriACLs, acl);
90 }
91
92 if(type.ptr) {
93 acl->type = type;
94 }
95 }
else if(sstrprefix(line, sstr(
"Authenticate "))) {
96 sstr_t param = sstrsubs(line,
13);
97 UcxList *plist = cfg_param_list(param, mp);
98 aclf->cur->authparam = plist;
99 }
else {
100 if(parse_ace(aclf, line)) {
101
102 return 1;
103 }
104 }
105
106 return 0;
107 }
108
109 int parse_ace(ACLFile *f,
sstr_t line) {
110 ACLConfig *cur = f->cur;
111 UcxAllocator *mp = f->parser.mp;
112
113 ssize_t tkn =
0;
114 sstr_t *tk = sstrsplit(line, sstr(
":"), &tkn);
115 if(!tk || tkn <
3) {
116 log_ereport(
LOG_FAILURE,
"parse_ace: to few tokens");
117 return 1;
118 }
119
120 ACEConfig *ace =
OBJ_NEW(mp, ACEConfig);
121 memset(ace,
0,
sizeof(ACEConfig));
122
123
124
125
126 int n =
0;
127 sstr_t s = tk[
0];
128
129 if(!sstrcmp(s, sstr(
"user"))) {
130
131 s = tk[
1];
132 n++;
133 ace->who = sstrdup_a(mp, s);
134 }
else if(!sstrcmp(s, sstr(
"group"))) {
135
136 s = tk[
1];
137 n++;
138 ace->who = sstrdup_a(mp, s);
139 ace->flags =
ACLCFG_IDENTIFIER_GROUP;
140 }
else if(!sstrcmp(s, sstr(
"owner@"))) {
141 ace->flags =
ACLCFG_OWNER;
142 }
else if(!sstrcmp(s, sstr(
"group@"))) {
143 ace->flags =
ACLCFG_GROUP;
144 }
else if(!sstrcmp(s, sstr(
"everyone@"))) {
145 ace->flags =
ACLCFG_EVERYONE;
146 }
else {
147
148 ace->who = sstrdup_a(mp, s);
149 }
150
151 n++;
152
153
154
155
156
157 if(n >= tkn) {
158
159 log_ereport(
LOG_FAILURE,
"parse_ace: ace incomplete");
160 return 1;
161 }
162 s = tk[n];
163
164 ssize_t maskn =
0;
165 sstr_t *accessmask = sstrsplit(s, sstr(
","), &maskn);
166 for(
int i=
0;i<maskn;i++) {
167 sstr_t access = accessmask[i];
168 ace->access_mask = ace->access_mask | accstr2int(access);
169 }
170 free(accessmask);
171 n++;
172
173
174
175
176
177 int complete =
0;
178 while(n < tkn) {
179 s = tk[n];
180 if(!sstrcmp(s, sstr(
"allow"))) {
181 ace->type =
ACLCFG_TYPE_ALLOWED;
182 complete =
1;
183 break;
184 }
else if(!sstrcmp(s, sstr(
"deny"))) {
185 ace->type =
ACLCFG_TYPE_DENIED;
186 complete =
1;
187 break;
188 }
else if(!sstrcmp(s, sstr(
"audit"))) {
189 ace->type =
ACLCFG_TYPE_AUDIT;
190 complete =
1;
191 break;
192 }
else if(!sstrcmp(s, sstr(
"alarm"))) {
193 ace->type =
ACLCFG_TYPE_ALARM;
194 complete =
1;
195 break;
196 }
else {
197
198 ssize_t fln =
0;
199 sstr_t *flags = sstrsplit(s, sstr(
","), &fln);
200 for(
int i=
0;i<fln;i++) {
201 sstr_t flag = flags[i];
202 if(!sstrcmp(flag, sstr(
"successful_access_flag"))) {
203 ace->flags = ace->flags |
ACLCFG_SUCCESSFUL_ACCESS_FLAG;
204 }
else if(!sstrcmp(flag, sstr(
"failed_access_flag"))) {
205 ace->flags = ace->flags |
ACLCFG_FAILED_ACCESS_ACE_FLAG;
206 }
207
208 }
209 free(flags);
210 }
211 n++;
212 }
213
214 if(!complete) {
215 log_ereport(
LOG_FAILURE,
"parse_ace: ace incomplete");
216 return 1;
217 }
218
219 cur->entries = ucx_list_append_a(mp, cur->entries, ace);
220
221 return 0;
222 }
223
224 uint32_t accstr2int(
sstr_t access) {
225 uint32_t val =
0;
226 if(!sstrcmp(access, sstr(
"read"))) {
227 val =
ACLCFG_READ;
228 }
else if(!sstrcmp(access, sstr(
"write"))) {
229 val =
ACLCFG_WRITE;
230 }
else if(!sstrcmp(access, sstr(
"read_data"))) {
231 val =
ACLCFG_READ_DATA;
232 }
else if(!sstrcmp(access, sstr(
"write_data"))) {
233 val =
ACLCFG_WRITE_DATA;
234 }
else if(!sstrcmp(access, sstr(
"append"))) {
235 val =
ACLCFG_APPEND;
236 }
else if(!sstrcmp(access, sstr(
"add"))) {
237 val =
ACLCFG_ADD_FILE;
238 }
else if(!sstrcmp(access, sstr(
"add_file"))) {
239 val =
ACLCFG_ADD_FILE;
240 }
else if(!sstrcmp(access, sstr(
"add_subdirectory"))) {
241 val =
ACLCFG_ADD_SUBDIRECTORY;
242 }
else if(!sstrcmp(access, sstr(
"read_xattr"))) {
243 val =
ACLCFG_READ_XATTR;
244 }
else if(!sstrcmp(access, sstr(
"write_xattr"))) {
245 val =
ACLCFG_WRITE_XATTR;
246 }
else if(!sstrcmp(access, sstr(
"execute"))) {
247 val =
ACLCFG_EXECUTE;
248 }
else if(!sstrcmp(access, sstr(
"delete_child"))) {
249 val =
ACLCFG_DELETE_CHILD;
250 }
else if(!sstrcmp(access, sstr(
"delete"))) {
251 val =
ACLCFG_DELETE;
252 }
else if(!sstrcmp(access, sstr(
"read_attributes"))) {
253 val =
ACLCFG_READ_ATTRIBUTES;
254 }
else if(!sstrcmp(access, sstr(
"write_attributes"))) {
255 val =
ACLCFG_WRITE_ATTRIBUTES;
256 }
else if(!sstrcmp(access, sstr(
"list"))) {
257 val =
ACLCFG_LIST;
258 }
else if(!sstrcmp(access, sstr(
"read_acl"))) {
259 val =
ACLCFG_READ_ACL;
260 }
else if(!sstrcmp(access, sstr(
"write_acl"))) {
261 val =
ACLCFG_WRITE_ACL;
262 }
else if(!sstrcmp(access, sstr(
"write_owner"))) {
263 val =
ACLCFG_WRITE_OWNER;
264 }
else if(!sstrcmp(access, sstr(
"synchronize"))) {
265 val =
ACLCFG_SYNCHRONIZE;
266 }
267 return val;
268 }
269