This source file includes following definitions.
- file_has_acl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
23 # pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
24 #endif
25
26 #include <config.h>
27
28 #include "acl.h"
29
30 #include "acl-internal.h"
31
32 #if GETXATTR_WITH_POSIX_ACLS
33 # include <sys/xattr.h>
34 # include <linux/xattr.h>
35 #endif
36
37
38
39
40
41
42
43
44 int
45 file_has_acl (char const *name, struct stat const *sb)
46 {
47 #if USE_ACL
48 if (! S_ISLNK (sb->st_mode))
49 {
50
51 # if GETXATTR_WITH_POSIX_ACLS
52
53 ssize_t ret;
54
55 ret = getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0);
56 if (ret < 0 && errno == ENODATA)
57 ret = 0;
58 else if (ret > 0)
59 return 1;
60
61 if (ret == 0 && S_ISDIR (sb->st_mode))
62 {
63 ret = getxattr (name, XATTR_NAME_POSIX_ACL_DEFAULT, NULL, 0);
64 if (ret < 0 && errno == ENODATA)
65 ret = 0;
66 else if (ret > 0)
67 return 1;
68 }
69
70 if (ret < 0)
71 return - acl_errno_valid (errno);
72 return ret;
73
74 # elif HAVE_ACL_GET_FILE
75
76
77
78 int ret;
79
80 if (HAVE_ACL_EXTENDED_FILE)
81 {
82
83
84
85 ret = acl_extended_file (name);
86 }
87 else
88 {
89 # if HAVE_ACL_TYPE_EXTENDED
90
91
92
93
94
95 acl_t acl = acl_get_file (name, ACL_TYPE_EXTENDED);
96 if (acl)
97 {
98 ret = acl_extended_nontrivial (acl);
99 acl_free (acl);
100 }
101 else
102 ret = -1;
103 # else
104 acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
105 if (acl)
106 {
107 int saved_errno;
108
109 ret = acl_access_nontrivial (acl);
110 saved_errno = errno;
111 acl_free (acl);
112 errno = saved_errno;
113 # if HAVE_ACL_FREE_TEXT
114
115
116
117 # else
118
119
120
121
122
123 if (ret == 0 && S_ISDIR (sb->st_mode))
124 {
125 acl = acl_get_file (name, ACL_TYPE_DEFAULT);
126 if (acl)
127 {
128 # ifdef __CYGWIN__
129 ret = acl_access_nontrivial (acl);
130 saved_errno = errno;
131 acl_free (acl);
132 errno = saved_errno;
133 # else
134 ret = (0 < acl_entries (acl));
135 acl_free (acl);
136 # endif
137 }
138 else
139 ret = -1;
140 }
141 # endif
142 }
143 else
144 ret = -1;
145 # endif
146 }
147 if (ret < 0)
148 return - acl_errno_valid (errno);
149 return ret;
150
151 # elif HAVE_FACL && defined GETACL
152
153 # if defined ACL_NO_TRIVIAL
154
155
156
157
158 return acl_trivial (name);
159
160 # else
161
162
163
164
165 {
166
167
168 enum
169 {
170 alloc_init = 4000 / sizeof (aclent_t),
171 alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (aclent_t))
172 };
173 aclent_t buf[alloc_init];
174 size_t alloc = alloc_init;
175 aclent_t *entries = buf;
176 aclent_t *malloced = NULL;
177 int count;
178
179 for (;;)
180 {
181 count = acl (name, GETACL, alloc, entries);
182 if (count < 0 && errno == ENOSPC)
183 {
184
185 free (malloced);
186 if (alloc > alloc_max / 2)
187 {
188 errno = ENOMEM;
189 return -1;
190 }
191 alloc = 2 * alloc;
192 entries = malloced =
193 (aclent_t *) malloc (alloc * sizeof (aclent_t));
194 if (entries == NULL)
195 {
196 errno = ENOMEM;
197 return -1;
198 }
199 continue;
200 }
201 break;
202 }
203 if (count < 0)
204 {
205 if (errno == ENOSYS || errno == ENOTSUP)
206 ;
207 else
208 {
209 free (malloced);
210 return -1;
211 }
212 }
213 else if (count == 0)
214 ;
215 else
216 {
217
218
219
220
221 if (count > 4)
222 {
223 free (malloced);
224 return 1;
225 }
226
227 if (acl_nontrivial (count, entries))
228 {
229 free (malloced);
230 return 1;
231 }
232 }
233 free (malloced);
234 }
235
236 # ifdef ACE_GETACL
237
238
239 {
240
241
242 enum
243 {
244 alloc_init = 4000 / sizeof (ace_t),
245 alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (ace_t))
246 };
247 ace_t buf[alloc_init];
248 size_t alloc = alloc_init;
249 ace_t *entries = buf;
250 ace_t *malloced = NULL;
251 int count;
252
253 for (;;)
254 {
255 count = acl (name, ACE_GETACL, alloc, entries);
256 if (count < 0 && errno == ENOSPC)
257 {
258
259 free (malloced);
260 if (alloc > alloc_max / 2)
261 {
262 errno = ENOMEM;
263 return -1;
264 }
265 alloc = 2 * alloc;
266 entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
267 if (entries == NULL)
268 {
269 errno = ENOMEM;
270 return -1;
271 }
272 continue;
273 }
274 break;
275 }
276 if (count < 0)
277 {
278 if (errno == ENOSYS || errno == EINVAL)
279 ;
280 else
281 {
282 free (malloced);
283 return -1;
284 }
285 }
286 else if (count == 0)
287 ;
288 else
289 {
290
291
292
293
294
295
296
297
298 if (count > 6)
299 {
300 free (malloced);
301 return 1;
302 }
303
304 if (acl_ace_nontrivial (count, entries))
305 {
306 free (malloced);
307 return 1;
308 }
309 }
310 free (malloced);
311 }
312 # endif
313
314 return 0;
315 # endif
316
317 # elif HAVE_GETACL
318
319 {
320 struct acl_entry entries[NACLENTRIES];
321 int count;
322
323 count = getacl (name, NACLENTRIES, entries);
324
325 if (count < 0)
326 {
327
328
329
330 if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
331 ;
332 else
333 return -1;
334 }
335 else if (count == 0)
336 return 0;
337 else
338 {
339 if (count > NACLENTRIES)
340
341
342 abort ();
343
344
345
346 if (count > 3)
347 return 1;
348
349 {
350 struct stat statbuf;
351
352 if (stat (name, &statbuf) == -1 && errno != EOVERFLOW)
353 return -1;
354
355 return acl_nontrivial (count, entries);
356 }
357 }
358 }
359
360 # if HAVE_ACLV_H
361
362 {
363 struct acl entries[NACLVENTRIES];
364 int count;
365
366 count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries);
367
368 if (count < 0)
369 {
370
371
372 if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
373 ;
374 else
375 return -1;
376 }
377 else if (count == 0)
378 return 0;
379 else
380 {
381 if (count > NACLVENTRIES)
382
383
384 abort ();
385
386
387
388 if (count > 4)
389 return 1;
390
391 return aclv_nontrivial (count, entries);
392 }
393 }
394
395 # endif
396
397 # elif HAVE_ACLX_GET && defined ACL_AIX_WIP
398
399 acl_type_t type;
400 char aclbuf[1024];
401 void *acl = aclbuf;
402 size_t aclsize = sizeof (aclbuf);
403 mode_t mode;
404
405 for (;;)
406 {
407
408
409 type.u64 = ACL_ANY;
410 if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0)
411 break;
412 if (errno == ENOSYS)
413 return 0;
414 if (errno != ENOSPC)
415 {
416 if (acl != aclbuf)
417 free (acl);
418 return -1;
419 }
420 aclsize = 2 * aclsize;
421 if (acl != aclbuf)
422 free (acl);
423 acl = malloc (aclsize);
424 if (acl == NULL)
425 {
426 errno = ENOMEM;
427 return -1;
428 }
429 }
430
431 if (type.u64 == ACL_AIXC)
432 {
433 int result = acl_nontrivial ((struct acl *) acl);
434 if (acl != aclbuf)
435 free (acl);
436 return result;
437 }
438 else if (type.u64 == ACL_NFS4)
439 {
440 int result = acl_nfs4_nontrivial ((nfs4_acl_int_t *) acl);
441 if (acl != aclbuf)
442 free (acl);
443 return result;
444 }
445 else
446 {
447
448
449 if (acl != aclbuf)
450 free (acl);
451 errno = EINVAL;
452 return -1;
453 }
454
455 # elif HAVE_STATACL
456
457 union { struct acl a; char room[4096]; } u;
458
459 if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0)
460 return -1;
461
462 return acl_nontrivial (&u.a);
463
464 # elif HAVE_ACLSORT
465
466 {
467 struct acl entries[NACLENTRIES];
468 int count;
469
470 count = acl ((char *) name, ACL_GET, NACLENTRIES, entries);
471
472 if (count < 0)
473 {
474 if (errno == ENOSYS || errno == ENOTSUP)
475 ;
476 else
477 return -1;
478 }
479 else if (count == 0)
480 return 0;
481 else
482 {
483 if (count > NACLENTRIES)
484
485
486 abort ();
487
488
489
490 if (count > 4)
491 return 1;
492
493 return acl_nontrivial (count, entries);
494 }
495 }
496
497 # endif
498 }
499 #endif
500
501 return 0;
502 }