Import upstream version 1.28
[debian/tar] / gnu / file-has-acl.c
1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Test whether a file has a nontrivial access control list.
4
5    Copyright (C) 2002-2003, 2005-2014 Free Software Foundation, Inc.
6
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20    Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible.  */
21
22 /* Without this pragma, gcc 4.7.0 20120126 may suggest that the
23    file_has_acl function might be candidate for attribute 'const'  */
24 #if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
25 # pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
26 #endif
27
28 #include <config.h>
29
30 #include "acl.h"
31
32 #include "acl-internal.h"
33
34
35 #if USE_ACL && HAVE_ACL_GET_FILE
36
37 # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
38
39 /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
40    Return 1 if the given ACL is non-trivial.
41    Return 0 if it is trivial.  */
42 int
43 acl_extended_nontrivial (acl_t acl)
44 {
45   /* acl is non-trivial if it is non-empty.  */
46   return (acl_entries (acl) > 0);
47 }
48
49 # else /* Linux, FreeBSD, IRIX, Tru64 */
50
51 /* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
52    Return 1 if the given ACL is non-trivial.
53    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
54    Return -1 and set errno upon failure to determine it.  */
55 int
56 acl_access_nontrivial (acl_t acl)
57 {
58   /* acl is non-trivial if it has some entries other than for "user::",
59      "group::", and "other::".  Normally these three should be present
60      at least, allowing us to write
61         return (3 < acl_entries (acl));
62      but the following code is more robust.  */
63 #  if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD */
64
65   acl_entry_t ace;
66   int got_one;
67
68   for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
69        got_one > 0;
70        got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
71     {
72       acl_tag_t tag;
73       if (acl_get_tag_type (ace, &tag) < 0)
74         return -1;
75       if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
76         return 1;
77     }
78   return got_one;
79
80 #  elif HAVE_ACL_TO_SHORT_TEXT /* IRIX */
81   /* Don't use acl_get_entry: it is undocumented.  */
82
83   int count = acl->acl_cnt;
84   int i;
85
86   for (i = 0; i < count; i++)
87     {
88       acl_entry_t ace = &acl->acl_entry[i];
89       acl_tag_t tag = ace->ae_tag;
90
91       if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ
92             || tag == ACL_OTHER_OBJ))
93         return 1;
94     }
95   return 0;
96
97 #  elif HAVE_ACL_FREE_TEXT /* Tru64 */
98   /* Don't use acl_get_entry: it takes only one argument and does not work.  */
99
100   int count = acl->acl_num;
101   acl_entry_t ace;
102
103   for (ace = acl->acl_first; count > 0; ace = ace->next, count--)
104     {
105       acl_tag_t tag;
106       acl_perm_t perm;
107
108       tag = ace->entry->acl_type;
109       if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
110         return 1;
111
112       perm = ace->entry->acl_perm;
113       /* On Tru64, perm can also contain non-standard bits such as
114          PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */
115       if ((perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)) != 0)
116         return 1;
117     }
118   return 0;
119
120 #  else
121
122   errno = ENOSYS;
123   return -1;
124 #  endif
125 }
126
127 # endif
128
129
130 #elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
131
132 /* Test an ACL retrieved with GETACL.
133    Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
134    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
135 int
136 acl_nontrivial (int count, aclent_t *entries)
137 {
138   int i;
139
140   for (i = 0; i < count; i++)
141     {
142       aclent_t *ace = &entries[i];
143
144       /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
145          If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
146          We don't need to check ace->a_id in these cases.  */
147       if (!(ace->a_type == USER_OBJ
148             || ace->a_type == GROUP_OBJ
149             || ace->a_type == OTHER_OBJ
150             /* Note: Cygwin does not return a CLASS_OBJ ("mask:") entry
151                sometimes.  */
152             || ace->a_type == CLASS_OBJ))
153         return 1;
154     }
155   return 0;
156 }
157
158 # ifdef ACE_GETACL
159
160 /* A shortcut for a bitmask.  */
161 #  define NEW_ACE_WRITEA_DATA (NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA)
162
163 /* Test an ACL retrieved with ACE_GETACL.
164    Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
165    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
166 int
167 acl_ace_nontrivial (int count, ace_t *entries)
168 {
169   int i;
170
171   /* The flags in the ace_t structure changed in a binary incompatible way
172      when ACL_NO_TRIVIAL etc. were introduced in <sys/acl.h> version 1.15.
173      How to distinguish the two conventions at runtime?
174      In the old convention, usually three ACEs have a_flags = ACE_OWNER /
175      ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400.  In the new
176      convention, these values are not used.  */
177   int old_convention = 0;
178
179   for (i = 0; i < count; i++)
180     if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER))
181       {
182         old_convention = 1;
183         break;
184       }
185
186   if (old_convention)
187     /* Running on Solaris 10.  */
188     for (i = 0; i < count; i++)
189       {
190         ace_t *ace = &entries[i];
191
192         /* Note:
193            If ace->a_flags = ACE_OWNER, ace->a_who is the st_uid from stat().
194            If ace->a_flags = ACE_GROUP, ace->a_who is the st_gid from stat().
195            We don't need to check ace->a_who in these cases.  */
196         if (!(ace->a_type == OLD_ALLOW
197               && (ace->a_flags == OLD_ACE_OWNER
198                   || ace->a_flags == OLD_ACE_GROUP
199                   || ace->a_flags == OLD_ACE_OTHER)))
200           return 1;
201       }
202   else
203     {
204       /* Running on Solaris 10 (newer version) or Solaris 11.  */
205       unsigned int access_masks[6] =
206         {
207           0, /* owner@ deny */
208           0, /* owner@ allow */
209           0, /* group@ deny */
210           0, /* group@ allow */
211           0, /* everyone@ deny */
212           0  /* everyone@ allow */
213         };
214
215       for (i = 0; i < count; i++)
216         {
217           ace_t *ace = &entries[i];
218           unsigned int index1;
219           unsigned int index2;
220
221           if (ace->a_type == NEW_ACE_ACCESS_ALLOWED_ACE_TYPE)
222             index1 = 1;
223           else if (ace->a_type == NEW_ACE_ACCESS_DENIED_ACE_TYPE)
224             index1 = 0;
225           else
226             return 1;
227
228           if (ace->a_flags == NEW_ACE_OWNER)
229             index2 = 0;
230           else if (ace->a_flags == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP))
231             index2 = 2;
232           else if (ace->a_flags == NEW_ACE_EVERYONE)
233             index2 = 4;
234           else
235             return 1;
236
237           access_masks[index1 + index2] |= ace->a_access_mask;
238         }
239
240       /* The same bit shouldn't be both allowed and denied.  */
241       if (access_masks[0] & access_masks[1])
242         return 1;
243       if (access_masks[2] & access_masks[3])
244         return 1;
245       if (access_masks[4] & access_masks[5])
246         return 1;
247
248       /* Check minimum masks.  */
249       if ((NEW_ACE_WRITE_NAMED_ATTRS
250            | NEW_ACE_WRITE_ATTRIBUTES
251            | NEW_ACE_WRITE_ACL
252            | NEW_ACE_WRITE_OWNER)
253           & ~ access_masks[1])
254         return 1;
255       access_masks[1] &= ~(NEW_ACE_WRITE_NAMED_ATTRS
256                            | NEW_ACE_WRITE_ATTRIBUTES
257                            | NEW_ACE_WRITE_ACL
258                            | NEW_ACE_WRITE_OWNER);
259       if ((NEW_ACE_READ_NAMED_ATTRS
260            | NEW_ACE_READ_ATTRIBUTES
261            | NEW_ACE_READ_ACL
262            | NEW_ACE_SYNCHRONIZE)
263           & ~ access_masks[5])
264         return 1;
265       access_masks[5] &= ~(NEW_ACE_READ_NAMED_ATTRS
266                            | NEW_ACE_READ_ATTRIBUTES
267                            | NEW_ACE_READ_ACL
268                            | NEW_ACE_SYNCHRONIZE);
269
270       /* Check the allowed or denied bits.  */
271       switch ((access_masks[0] | access_masks[1])
272               & ~(NEW_ACE_READ_NAMED_ATTRS
273                   | NEW_ACE_READ_ATTRIBUTES
274                   | NEW_ACE_READ_ACL
275                   | NEW_ACE_SYNCHRONIZE))
276         {
277         case 0:
278         case NEW_ACE_READ_DATA:
279         case                     NEW_ACE_WRITEA_DATA:
280         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
281         case                                           NEW_ACE_EXECUTE:
282         case NEW_ACE_READ_DATA |                       NEW_ACE_EXECUTE:
283         case                     NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
284         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
285           break;
286         default:
287           return 1;
288         }
289       switch ((access_masks[2] | access_masks[3])
290               & ~(NEW_ACE_READ_NAMED_ATTRS
291                   | NEW_ACE_READ_ATTRIBUTES
292                   | NEW_ACE_READ_ACL
293                   | NEW_ACE_SYNCHRONIZE))
294         {
295         case 0:
296         case NEW_ACE_READ_DATA:
297         case                     NEW_ACE_WRITEA_DATA:
298         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
299         case                                           NEW_ACE_EXECUTE:
300         case NEW_ACE_READ_DATA |                       NEW_ACE_EXECUTE:
301         case                     NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
302         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
303           break;
304         default:
305           return 1;
306         }
307       switch ((access_masks[4] | access_masks[5])
308               & ~(NEW_ACE_WRITE_NAMED_ATTRS
309                   | NEW_ACE_WRITE_ATTRIBUTES
310                   | NEW_ACE_WRITE_ACL
311                   | NEW_ACE_WRITE_OWNER))
312         {
313         case 0:
314         case NEW_ACE_READ_DATA:
315         case                     NEW_ACE_WRITEA_DATA:
316         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
317         case                                           NEW_ACE_EXECUTE:
318         case NEW_ACE_READ_DATA |                       NEW_ACE_EXECUTE:
319         case                     NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
320         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
321           break;
322         default:
323           return 1;
324         }
325
326       /* Check that the NEW_ACE_WRITE_DATA and NEW_ACE_APPEND_DATA bits are
327          either both allowed or both denied.  */
328       if (((access_masks[0] & NEW_ACE_WRITE_DATA) != 0)
329           != ((access_masks[0] & NEW_ACE_APPEND_DATA) != 0))
330         return 1;
331       if (((access_masks[2] & NEW_ACE_WRITE_DATA) != 0)
332           != ((access_masks[2] & NEW_ACE_APPEND_DATA) != 0))
333         return 1;
334       if (((access_masks[4] & NEW_ACE_WRITE_DATA) != 0)
335           != ((access_masks[4] & NEW_ACE_APPEND_DATA) != 0))
336         return 1;
337     }
338
339   return 0;
340 }
341
342 # endif
343
344 #elif USE_ACL && HAVE_GETACL /* HP-UX */
345
346 /* Return 1 if the given ACL is non-trivial.
347    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
348 int
349 acl_nontrivial (int count, struct acl_entry *entries, struct stat *sb)
350 {
351   int i;
352
353   for (i = 0; i < count; i++)
354     {
355       struct acl_entry *ace = &entries[i];
356
357       if (!((ace->uid == sb->st_uid && ace->gid == ACL_NSGROUP)
358             || (ace->uid == ACL_NSUSER && ace->gid == sb->st_gid)
359             || (ace->uid == ACL_NSUSER && ace->gid == ACL_NSGROUP)))
360         return 1;
361     }
362   return 0;
363 }
364
365 # if HAVE_ACLV_H /* HP-UX >= 11.11 */
366
367 /* Return 1 if the given ACL is non-trivial.
368    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
369 int
370 aclv_nontrivial (int count, struct acl *entries)
371 {
372   int i;
373
374   for (i = 0; i < count; i++)
375     {
376       struct acl *ace = &entries[i];
377
378       /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
379          If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
380          We don't need to check ace->a_id in these cases.  */
381       if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
382             || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
383             || ace->a_type == CLASS_OBJ
384             || ace->a_type == OTHER_OBJ))
385         return 1;
386     }
387   return 0;
388 }
389
390 # endif
391
392 #elif USE_ACL && (HAVE_ACLX_GET || HAVE_STATACL) /* AIX */
393
394 /* Return 1 if the given ACL is non-trivial.
395    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
396 int
397 acl_nontrivial (struct acl *a)
398 {
399   /* The normal way to iterate through an ACL is like this:
400        struct acl_entry *ace;
401        for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace))
402          {
403            struct ace_id *aei;
404            switch (ace->ace_type)
405              {
406              case ACC_PERMIT:
407              case ACC_DENY:
408              case ACC_SPECIFY:
409                ...;
410              }
411            for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei))
412              ...
413          }
414    */
415   return (acl_last (a) != a->acl_ext ? 1 : 0);
416 }
417
418 # if HAVE_ACLX_GET && defined ACL_AIX_WIP /* newer AIX */
419
420 /* Return 1 if the given ACL is non-trivial.
421    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
422 int
423 acl_nfs4_nontrivial (nfs4_acl_int_t *a)
424 {
425 #  if 1 /* let's try this first */
426   return (a->aclEntryN > 0 ? 1 : 0);
427 #  else
428   int count = a->aclEntryN;
429   int i;
430
431   for (i = 0; i < count; i++)
432     {
433       nfs4_ace_int_t *ace = &a->aclEntry[i];
434
435       if (!((ace->flags & ACE4_ID_SPECIAL) != 0
436             && (ace->aceWho.special_whoid == ACE4_WHO_OWNER
437                 || ace->aceWho.special_whoid == ACE4_WHO_GROUP
438                 || ace->aceWho.special_whoid == ACE4_WHO_EVERYONE)
439             && ace->aceType == ACE4_ACCESS_ALLOWED_ACE_TYPE
440             && ace->aceFlags == 0
441             && (ace->aceMask & ~(ACE4_READ_DATA | ACE4_LIST_DIRECTORY
442                                  | ACE4_WRITE_DATA | ACE4_ADD_FILE
443                                  | ACE4_EXECUTE)) == 0))
444         return 1;
445     }
446   return 0;
447 #  endif
448 }
449
450 # endif
451
452 #elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */
453
454 /* Test an ACL retrieved with ACL_GET.
455    Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
456    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
457 int
458 acl_nontrivial (int count, struct acl *entries)
459 {
460   int i;
461
462   for (i = 0; i < count; i++)
463     {
464       struct acl *ace = &entries[i];
465
466       /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
467          If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
468          We don't need to check ace->a_id in these cases.  */
469       if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
470             || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
471             || ace->a_type == CLASS_OBJ
472             || ace->a_type == OTHER_OBJ))
473         return 1;
474     }
475   return 0;
476 }
477
478 #endif
479
480
481 /* Return 1 if NAME has a nontrivial access control list, 0 if NAME
482    only has no or a base access control list, and -1 (setting errno)
483    on error.  SB must be set to the stat buffer of NAME, obtained
484    through stat() or lstat().  */
485
486 int
487 file_has_acl (char const *name, struct stat const *sb)
488 {
489 #if USE_ACL
490   if (! S_ISLNK (sb->st_mode))
491     {
492 # if HAVE_ACL_GET_FILE
493
494       /* POSIX 1003.1e (draft 17 -- abandoned) specific version.  */
495       /* Linux, FreeBSD, Mac OS X, IRIX, Tru64 */
496       int ret;
497
498       if (HAVE_ACL_EXTENDED_FILE) /* Linux */
499         {
500           /* On Linux, acl_extended_file is an optimized function: It only
501              makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
502              ACL_TYPE_DEFAULT.  */
503           ret = acl_extended_file (name);
504         }
505       else /* FreeBSD, Mac OS X, IRIX, Tru64 */
506         {
507 #  if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
508           /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)
509              and acl_get_file (name, ACL_TYPE_DEFAULT)
510              always return NULL / EINVAL.  There is no point in making
511              these two useless calls.  The real ACL is retrieved through
512              acl_get_file (name, ACL_TYPE_EXTENDED).  */
513           acl_t acl = acl_get_file (name, ACL_TYPE_EXTENDED);
514           if (acl)
515             {
516               ret = acl_extended_nontrivial (acl);
517               acl_free (acl);
518             }
519           else
520             ret = -1;
521 #  else /* FreeBSD, IRIX, Tru64 */
522           acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
523           if (acl)
524             {
525               int saved_errno;
526
527               ret = acl_access_nontrivial (acl);
528               saved_errno = errno;
529               acl_free (acl);
530               errno = saved_errno;
531 #   if HAVE_ACL_FREE_TEXT /* Tru64 */
532               /* On OSF/1, acl_get_file (name, ACL_TYPE_DEFAULT) always
533                  returns NULL with errno not set.  There is no point in
534                  making this call.  */
535 #   else /* FreeBSD, IRIX */
536               /* On Linux, FreeBSD, IRIX, acl_get_file (name, ACL_TYPE_ACCESS)
537                  and acl_get_file (name, ACL_TYPE_DEFAULT) on a directory
538                  either both succeed or both fail; it depends on the
539                  file system.  Therefore there is no point in making the second
540                  call if the first one already failed.  */
541               if (ret == 0 && S_ISDIR (sb->st_mode))
542                 {
543                   acl = acl_get_file (name, ACL_TYPE_DEFAULT);
544                   if (acl)
545                     {
546                       ret = (0 < acl_entries (acl));
547                       acl_free (acl);
548                     }
549                   else
550                     ret = -1;
551                 }
552 #   endif
553             }
554           else
555             ret = -1;
556 #  endif
557         }
558       if (ret < 0)
559         return - acl_errno_valid (errno);
560       return ret;
561
562 # elif HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
563
564 #  if defined ACL_NO_TRIVIAL
565
566       /* Solaris 10 (newer version), which has additional API declared in
567          <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial,
568          acl_fromtext, ...).  */
569       return acl_trivial (name);
570
571 #  else /* Solaris, Cygwin, general case */
572
573       /* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions
574          of Unixware.  The acl() call returns the access and default ACL both
575          at once.  */
576       {
577         /* Initially, try to read the entries into a stack-allocated buffer.
578            Use malloc if it does not fit.  */
579         enum
580           {
581             alloc_init = 4000 / sizeof (aclent_t), /* >= 3 */
582             alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (aclent_t))
583           };
584         aclent_t buf[alloc_init];
585         size_t alloc = alloc_init;
586         aclent_t *entries = buf;
587         aclent_t *malloced = NULL;
588         int count;
589
590         for (;;)
591           {
592             count = acl (name, GETACL, alloc, entries);
593             if (count < 0 && errno == ENOSPC)
594               {
595                 /* Increase the size of the buffer.  */
596                 free (malloced);
597                 if (alloc > alloc_max / 2)
598                   {
599                     errno = ENOMEM;
600                     return -1;
601                   }
602                 alloc = 2 * alloc; /* <= alloc_max */
603                 entries = malloced =
604                   (aclent_t *) malloc (alloc * sizeof (aclent_t));
605                 if (entries == NULL)
606                   {
607                     errno = ENOMEM;
608                     return -1;
609                   }
610                 continue;
611               }
612             break;
613           }
614         if (count < 0)
615           {
616             if (errno == ENOSYS || errno == ENOTSUP)
617               ;
618             else
619               {
620                 int saved_errno = errno;
621                 free (malloced);
622                 errno = saved_errno;
623                 return -1;
624               }
625           }
626         else if (count == 0)
627           ;
628         else
629           {
630             /* Don't use MIN_ACL_ENTRIES:  It's set to 4 on Cygwin, but Cygwin
631                returns only 3 entries for files with no ACL.  But this is safe:
632                If there are more than 4 entries, there cannot be only the
633                "user::", "group::", "other:", and "mask:" entries.  */
634             if (count > 4)
635               {
636                 free (malloced);
637                 return 1;
638               }
639
640             if (acl_nontrivial (count, entries))
641               {
642                 free (malloced);
643                 return 1;
644               }
645           }
646         free (malloced);
647       }
648
649 #   ifdef ACE_GETACL
650       /* Solaris also has a different variant of ACLs, used in ZFS and NFSv4
651          file systems (whereas the other ones are used in UFS file systems).  */
652       {
653         /* Initially, try to read the entries into a stack-allocated buffer.
654            Use malloc if it does not fit.  */
655         enum
656           {
657             alloc_init = 4000 / sizeof (ace_t), /* >= 3 */
658             alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (ace_t))
659           };
660         ace_t buf[alloc_init];
661         size_t alloc = alloc_init;
662         ace_t *entries = buf;
663         ace_t *malloced = NULL;
664         int count;
665
666         for (;;)
667           {
668             count = acl (name, ACE_GETACL, alloc, entries);
669             if (count < 0 && errno == ENOSPC)
670               {
671                 /* Increase the size of the buffer.  */
672                 free (malloced);
673                 if (alloc > alloc_max / 2)
674                   {
675                     errno = ENOMEM;
676                     return -1;
677                   }
678                 alloc = 2 * alloc; /* <= alloc_max */
679                 entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
680                 if (entries == NULL)
681                   {
682                     errno = ENOMEM;
683                     return -1;
684                   }
685                 continue;
686               }
687             break;
688           }
689         if (count < 0)
690           {
691             if (errno == ENOSYS || errno == EINVAL)
692               ;
693             else
694               {
695                 int saved_errno = errno;
696                 free (malloced);
697                 errno = saved_errno;
698                 return -1;
699               }
700           }
701         else if (count == 0)
702           ;
703         else
704           {
705             /* In the old (original Solaris 10) convention:
706                If there are more than 3 entries, there cannot be only the
707                ACE_OWNER, ACE_GROUP, ACE_OTHER entries.
708                In the newer Solaris 10 and Solaris 11 convention:
709                If there are more than 6 entries, there cannot be only the
710                ACE_OWNER, ACE_GROUP, ACE_EVERYONE entries, each once with
711                NEW_ACE_ACCESS_ALLOWED_ACE_TYPE and once with
712                NEW_ACE_ACCESS_DENIED_ACE_TYPE.  */
713             if (count > 6)
714               {
715                 free (malloced);
716                 return 1;
717               }
718
719             if (acl_ace_nontrivial (count, entries))
720               {
721                 free (malloced);
722                 return 1;
723               }
724           }
725         free (malloced);
726       }
727 #   endif
728
729       return 0;
730 #  endif
731
732 # elif HAVE_GETACL /* HP-UX */
733
734       {
735         struct acl_entry entries[NACLENTRIES];
736         int count;
737
738         count = getacl (name, NACLENTRIES, entries);
739
740         if (count < 0)
741           {
742             /* ENOSYS is seen on newer HP-UX versions.
743                EOPNOTSUPP is typically seen on NFS mounts.
744                ENOTSUP was seen on Quantum StorNext file systems (cvfs).  */
745             if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)
746               ;
747             else
748               return -1;
749           }
750         else if (count == 0)
751           return 0;
752         else /* count > 0 */
753           {
754             if (count > NACLENTRIES)
755               /* If NACLENTRIES cannot be trusted, use dynamic memory
756                  allocation.  */
757               abort ();
758
759             /* If there are more than 3 entries, there cannot be only the
760                (uid,%), (%,gid), (%,%) entries.  */
761             if (count > 3)
762               return 1;
763
764             {
765               struct stat statbuf;
766
767               if (stat (name, &statbuf) < 0)
768                 return -1;
769
770               return acl_nontrivial (count, entries, &statbuf);
771             }
772           }
773       }
774
775 #  if HAVE_ACLV_H /* HP-UX >= 11.11 */
776
777       {
778         struct acl entries[NACLVENTRIES];
779         int count;
780
781         count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries);
782
783         if (count < 0)
784           {
785             /* EOPNOTSUPP is seen on NFS in HP-UX 11.11, 11.23.
786                EINVAL is seen on NFS in HP-UX 11.31.  */
787             if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)
788               ;
789             else
790               return -1;
791           }
792         else if (count == 0)
793           return 0;
794         else /* count > 0 */
795           {
796             if (count > NACLVENTRIES)
797               /* If NACLVENTRIES cannot be trusted, use dynamic memory
798                  allocation.  */
799               abort ();
800
801             /* If there are more than 4 entries, there cannot be only the
802                four base ACL entries.  */
803             if (count > 4)
804               return 1;
805
806             return aclv_nontrivial (count, entries);
807           }
808       }
809
810 #  endif
811
812 # elif HAVE_ACLX_GET && defined ACL_AIX_WIP /* AIX */
813
814       acl_type_t type;
815       char aclbuf[1024];
816       void *acl = aclbuf;
817       size_t aclsize = sizeof (aclbuf);
818       mode_t mode;
819
820       for (;;)
821         {
822           /* The docs say that type being 0 is equivalent to ACL_ANY, but it
823              is not true, in AIX 5.3.  */
824           type.u64 = ACL_ANY;
825           if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0)
826             break;
827           if (errno == ENOSYS)
828             return 0;
829           if (errno != ENOSPC)
830             {
831               if (acl != aclbuf)
832                 {
833                   int saved_errno = errno;
834                   free (acl);
835                   errno = saved_errno;
836                 }
837               return -1;
838             }
839           aclsize = 2 * aclsize;
840           if (acl != aclbuf)
841             free (acl);
842           acl = malloc (aclsize);
843           if (acl == NULL)
844             {
845               errno = ENOMEM;
846               return -1;
847             }
848         }
849
850       if (type.u64 == ACL_AIXC)
851         {
852           int result = acl_nontrivial ((struct acl *) acl);
853           if (acl != aclbuf)
854             free (acl);
855           return result;
856         }
857       else if (type.u64 == ACL_NFS4)
858         {
859           int result = acl_nfs4_nontrivial ((nfs4_acl_int_t *) acl);
860           if (acl != aclbuf)
861             free (acl);
862           return result;
863         }
864       else
865         {
866           /* A newer type of ACL has been introduced in the system.
867              We should better support it.  */
868           if (acl != aclbuf)
869             free (acl);
870           errno = EINVAL;
871           return -1;
872         }
873
874 # elif HAVE_STATACL /* older AIX */
875
876       union { struct acl a; char room[4096]; } u;
877
878       if (statacl (name, STX_NORMAL, &u.a, sizeof (u)) < 0)
879         return -1;
880
881       return acl_nontrivial (&u.a);
882
883 # elif HAVE_ACLSORT /* NonStop Kernel */
884
885       {
886         struct acl entries[NACLENTRIES];
887         int count;
888
889         count = acl ((char *) name, ACL_GET, NACLENTRIES, entries);
890
891         if (count < 0)
892           {
893             if (errno == ENOSYS || errno == ENOTSUP)
894               ;
895             else
896               return -1;
897           }
898         else if (count == 0)
899           return 0;
900         else /* count > 0 */
901           {
902             if (count > NACLENTRIES)
903               /* If NACLENTRIES cannot be trusted, use dynamic memory
904                  allocation.  */
905               abort ();
906
907             /* If there are more than 4 entries, there cannot be only the
908                four base ACL entries.  */
909             if (count > 4)
910               return 1;
911
912             return acl_nontrivial (count, entries);
913           }
914       }
915
916 # endif
917     }
918 #endif
919
920   return 0;
921 }