Import upstream version 1.29
[debian/tar] / gnu / acl-internal.c
1 /* Test whether a file has a nontrivial access control list.
2
3    Copyright (C) 2002-2003, 2005-2015 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18    Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible.  */
19
20 #include <config.h>
21
22 #include "acl.h"
23
24 #include "acl-internal.h"
25
26 #if USE_ACL && HAVE_ACL_GET_FILE
27
28 # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
29
30 /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
31    Return 1 if the given ACL is non-trivial.
32    Return 0 if it is trivial.  */
33 int
34 acl_extended_nontrivial (acl_t acl)
35 {
36   /* acl is non-trivial if it is non-empty.  */
37   return (acl_entries (acl) > 0);
38 }
39
40 # else /* Linux, FreeBSD, IRIX, Tru64 */
41
42 /* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
43    Return 1 if the given ACL is non-trivial.
44    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
45    Return -1 and set errno upon failure to determine it.  */
46 int
47 acl_access_nontrivial (acl_t acl)
48 {
49   /* acl is non-trivial if it has some entries other than for "user::",
50      "group::", and "other::".  Normally these three should be present
51      at least, allowing us to write
52         return (3 < acl_entries (acl));
53      but the following code is more robust.  */
54 #  if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD */
55
56   acl_entry_t ace;
57   int got_one;
58
59   for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
60        got_one > 0;
61        got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
62     {
63       acl_tag_t tag;
64       if (acl_get_tag_type (ace, &tag) < 0)
65         return -1;
66       if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
67         return 1;
68     }
69   return got_one;
70
71 #  elif HAVE_ACL_TO_SHORT_TEXT /* IRIX */
72   /* Don't use acl_get_entry: it is undocumented.  */
73
74   int count = acl->acl_cnt;
75   int i;
76
77   for (i = 0; i < count; i++)
78     {
79       acl_entry_t ace = &acl->acl_entry[i];
80       acl_tag_t tag = ace->ae_tag;
81
82       if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ
83             || tag == ACL_OTHER_OBJ))
84         return 1;
85     }
86   return 0;
87
88 #  elif HAVE_ACL_FREE_TEXT /* Tru64 */
89   /* Don't use acl_get_entry: it takes only one argument and does not work.  */
90
91   int count = acl->acl_num;
92   acl_entry_t ace;
93
94   for (ace = acl->acl_first; count > 0; ace = ace->next, count--)
95     {
96       acl_tag_t tag;
97       acl_perm_t perm;
98
99       tag = ace->entry->acl_type;
100       if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
101         return 1;
102
103       perm = ace->entry->acl_perm;
104       /* On Tru64, perm can also contain non-standard bits such as
105          PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */
106       if ((perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)) != 0)
107         return 1;
108     }
109   return 0;
110
111 #  else
112
113   errno = ENOSYS;
114   return -1;
115 #  endif
116 }
117
118 int
119 acl_default_nontrivial (acl_t acl)
120 {
121   /* acl is non-trivial if it is non-empty.  */
122   return (acl_entries (acl) > 0);
123 }
124
125 # endif
126
127 #elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
128
129 /* Test an ACL retrieved with GETACL.
130    Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
131    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
132 int
133 acl_nontrivial (int count, aclent_t *entries)
134 {
135   int i;
136
137   for (i = 0; i < count; i++)
138     {
139       aclent_t *ace = &entries[i];
140
141       /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
142          If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
143          We don't need to check ace->a_id in these cases.  */
144       if (!(ace->a_type == USER_OBJ
145             || ace->a_type == GROUP_OBJ
146             || ace->a_type == OTHER_OBJ
147             /* Note: Cygwin does not return a CLASS_OBJ ("mask:") entry
148                sometimes.  */
149             || ace->a_type == CLASS_OBJ))
150         return 1;
151     }
152   return 0;
153 }
154
155 # ifdef ACE_GETACL
156
157 /* A shortcut for a bitmask.  */
158 #  define NEW_ACE_WRITEA_DATA (NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA)
159
160 /* Test an ACL retrieved with ACE_GETACL.
161    Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
162    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
163 int
164 acl_ace_nontrivial (int count, ace_t *entries)
165 {
166   int i;
167
168   /* The flags in the ace_t structure changed in a binary incompatible way
169      when ACL_NO_TRIVIAL etc. were introduced in <sys/acl.h> version 1.15.
170      How to distinguish the two conventions at runtime?
171      In the old convention, usually three ACEs have a_flags = ACE_OWNER /
172      ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400.  In the new
173      convention, these values are not used.  */
174   int old_convention = 0;
175
176   for (i = 0; i < count; i++)
177     if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER))
178       {
179         old_convention = 1;
180         break;
181       }
182
183   if (old_convention)
184     /* Running on Solaris 10.  */
185     for (i = 0; i < count; i++)
186       {
187         ace_t *ace = &entries[i];
188
189         /* Note:
190            If ace->a_flags = ACE_OWNER, ace->a_who is the st_uid from stat().
191            If ace->a_flags = ACE_GROUP, ace->a_who is the st_gid from stat().
192            We don't need to check ace->a_who in these cases.  */
193         if (!(ace->a_type == OLD_ALLOW
194               && (ace->a_flags == OLD_ACE_OWNER
195                   || ace->a_flags == OLD_ACE_GROUP
196                   || ace->a_flags == OLD_ACE_OTHER)))
197           return 1;
198       }
199   else
200     {
201       /* Running on Solaris 10 (newer version) or Solaris 11.  */
202       unsigned int access_masks[6] =
203         {
204           0, /* owner@ deny */
205           0, /* owner@ allow */
206           0, /* group@ deny */
207           0, /* group@ allow */
208           0, /* everyone@ deny */
209           0  /* everyone@ allow */
210         };
211
212       for (i = 0; i < count; i++)
213         {
214           ace_t *ace = &entries[i];
215           unsigned int index1;
216           unsigned int index2;
217
218           if (ace->a_type == NEW_ACE_ACCESS_ALLOWED_ACE_TYPE)
219             index1 = 1;
220           else if (ace->a_type == NEW_ACE_ACCESS_DENIED_ACE_TYPE)
221             index1 = 0;
222           else
223             return 1;
224
225           if (ace->a_flags == NEW_ACE_OWNER)
226             index2 = 0;
227           else if (ace->a_flags == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP))
228             index2 = 2;
229           else if (ace->a_flags == NEW_ACE_EVERYONE)
230             index2 = 4;
231           else
232             return 1;
233
234           access_masks[index1 + index2] |= ace->a_access_mask;
235         }
236
237       /* The same bit shouldn't be both allowed and denied.  */
238       if (access_masks[0] & access_masks[1])
239         return 1;
240       if (access_masks[2] & access_masks[3])
241         return 1;
242       if (access_masks[4] & access_masks[5])
243         return 1;
244
245       /* Check minimum masks.  */
246       if ((NEW_ACE_WRITE_NAMED_ATTRS
247            | NEW_ACE_WRITE_ATTRIBUTES
248            | NEW_ACE_WRITE_ACL
249            | NEW_ACE_WRITE_OWNER)
250           & ~ access_masks[1])
251         return 1;
252       access_masks[1] &= ~(NEW_ACE_WRITE_NAMED_ATTRS
253                            | NEW_ACE_WRITE_ATTRIBUTES
254                            | NEW_ACE_WRITE_ACL
255                            | NEW_ACE_WRITE_OWNER);
256       if ((NEW_ACE_READ_NAMED_ATTRS
257            | NEW_ACE_READ_ATTRIBUTES
258            | NEW_ACE_READ_ACL
259            | NEW_ACE_SYNCHRONIZE)
260           & ~ access_masks[5])
261         return 1;
262       access_masks[5] &= ~(NEW_ACE_READ_NAMED_ATTRS
263                            | NEW_ACE_READ_ATTRIBUTES
264                            | NEW_ACE_READ_ACL
265                            | NEW_ACE_SYNCHRONIZE);
266
267       /* Check the allowed or denied bits.  */
268       switch ((access_masks[0] | access_masks[1])
269               & ~(NEW_ACE_READ_NAMED_ATTRS
270                   | NEW_ACE_READ_ATTRIBUTES
271                   | NEW_ACE_READ_ACL
272                   | NEW_ACE_SYNCHRONIZE))
273         {
274         case 0:
275         case NEW_ACE_READ_DATA:
276         case                     NEW_ACE_WRITEA_DATA:
277         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
278         case                                           NEW_ACE_EXECUTE:
279         case NEW_ACE_READ_DATA |                       NEW_ACE_EXECUTE:
280         case                     NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
281         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
282           break;
283         default:
284           return 1;
285         }
286       switch ((access_masks[2] | access_masks[3])
287               & ~(NEW_ACE_READ_NAMED_ATTRS
288                   | NEW_ACE_READ_ATTRIBUTES
289                   | NEW_ACE_READ_ACL
290                   | NEW_ACE_SYNCHRONIZE))
291         {
292         case 0:
293         case NEW_ACE_READ_DATA:
294         case                     NEW_ACE_WRITEA_DATA:
295         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
296         case                                           NEW_ACE_EXECUTE:
297         case NEW_ACE_READ_DATA |                       NEW_ACE_EXECUTE:
298         case                     NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
299         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
300           break;
301         default:
302           return 1;
303         }
304       switch ((access_masks[4] | access_masks[5])
305               & ~(NEW_ACE_WRITE_NAMED_ATTRS
306                   | NEW_ACE_WRITE_ATTRIBUTES
307                   | NEW_ACE_WRITE_ACL
308                   | NEW_ACE_WRITE_OWNER))
309         {
310         case 0:
311         case NEW_ACE_READ_DATA:
312         case                     NEW_ACE_WRITEA_DATA:
313         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
314         case                                           NEW_ACE_EXECUTE:
315         case NEW_ACE_READ_DATA |                       NEW_ACE_EXECUTE:
316         case                     NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
317         case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
318           break;
319         default:
320           return 1;
321         }
322
323       /* Check that the NEW_ACE_WRITE_DATA and NEW_ACE_APPEND_DATA bits are
324          either both allowed or both denied.  */
325       if (((access_masks[0] & NEW_ACE_WRITE_DATA) != 0)
326           != ((access_masks[0] & NEW_ACE_APPEND_DATA) != 0))
327         return 1;
328       if (((access_masks[2] & NEW_ACE_WRITE_DATA) != 0)
329           != ((access_masks[2] & NEW_ACE_APPEND_DATA) != 0))
330         return 1;
331       if (((access_masks[4] & NEW_ACE_WRITE_DATA) != 0)
332           != ((access_masks[4] & NEW_ACE_APPEND_DATA) != 0))
333         return 1;
334     }
335
336   return 0;
337 }
338
339 # endif
340
341 #elif USE_ACL && HAVE_GETACL /* HP-UX */
342
343 /* Return 1 if the given ACL is non-trivial.
344    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
345 int
346 acl_nontrivial (int count, struct acl_entry *entries)
347 {
348   int i;
349
350   if (count > 3)
351     return 1;
352
353   for (i = 0; i < count; i++)
354     {
355       struct acl_entry *ace = &entries[i];
356
357       if (ace->uid != ACL_NSUSER && ace->gid != ACL_NSGROUP)
358         return 1;
359     }
360   return 0;
361 }
362
363 # if HAVE_ACLV_H /* HP-UX >= 11.11 */
364
365 /* Return 1 if the given ACL is non-trivial.
366    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
367 int
368 aclv_nontrivial (int count, struct acl *entries)
369 {
370   int i;
371
372   for (i = 0; i < count; i++)
373     {
374       struct acl *ace = &entries[i];
375
376       /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
377          If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
378          We don't need to check ace->a_id in these cases.  */
379       if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
380             || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
381             || ace->a_type == CLASS_OBJ
382             || ace->a_type == OTHER_OBJ))
383         return 1;
384     }
385   return 0;
386 }
387
388 # endif
389
390 #elif USE_ACL && (HAVE_ACLX_GET || HAVE_STATACL) /* AIX */
391
392 /* Return 1 if the given ACL is non-trivial.
393    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
394 int
395 acl_nontrivial (struct acl *a)
396 {
397   /* The normal way to iterate through an ACL is like this:
398        struct acl_entry *ace;
399        for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace))
400          {
401            struct ace_id *aei;
402            switch (ace->ace_type)
403              {
404              case ACC_PERMIT:
405              case ACC_DENY:
406              case ACC_SPECIFY:
407                ...;
408              }
409            for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei))
410              ...
411          }
412    */
413   return (acl_last (a) != a->acl_ext ? 1 : 0);
414 }
415
416 # if HAVE_ACLX_GET && defined ACL_AIX_WIP /* newer AIX */
417
418 /* Return 1 if the given ACL is non-trivial.
419    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
420 int
421 acl_nfs4_nontrivial (nfs4_acl_int_t *a)
422 {
423 #  if 1 /* let's try this first */
424   return (a->aclEntryN > 0 ? 1 : 0);
425 #  else
426   int count = a->aclEntryN;
427   int i;
428
429   for (i = 0; i < count; i++)
430     {
431       nfs4_ace_int_t *ace = &a->aclEntry[i];
432
433       if (!((ace->flags & ACE4_ID_SPECIAL) != 0
434             && (ace->aceWho.special_whoid == ACE4_WHO_OWNER
435                 || ace->aceWho.special_whoid == ACE4_WHO_GROUP
436                 || ace->aceWho.special_whoid == ACE4_WHO_EVERYONE)
437             && ace->aceType == ACE4_ACCESS_ALLOWED_ACE_TYPE
438             && ace->aceFlags == 0
439             && (ace->aceMask & ~(ACE4_READ_DATA | ACE4_LIST_DIRECTORY
440                                  | ACE4_WRITE_DATA | ACE4_ADD_FILE
441                                  | ACE4_EXECUTE)) == 0))
442         return 1;
443     }
444   return 0;
445 #  endif
446 }
447
448 # endif
449
450 #elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */
451
452 /* Test an ACL retrieved with ACL_GET.
453    Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
454    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
455 int
456 acl_nontrivial (int count, struct acl *entries)
457 {
458   int i;
459
460   for (i = 0; i < count; i++)
461     {
462       struct acl *ace = &entries[i];
463
464       /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
465          If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
466          We don't need to check ace->a_id in these cases.  */
467       if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
468             || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
469             || ace->a_type == CLASS_OBJ
470             || ace->a_type == OTHER_OBJ))
471         return 1;
472     }
473   return 0;
474 }
475
476 #endif
477
478 void
479 free_permission_context (struct permission_context *ctx)
480 {
481 #ifdef USE_ACL
482 # if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64 */
483   if (ctx->acl)
484     acl_free (ctx->acl);
485 #  if !HAVE_ACL_TYPE_EXTENDED
486   if (ctx->default_acl)
487     acl_free (ctx->default_acl);
488 #  endif
489
490 # elif defined GETACL /* Solaris, Cygwin */
491   free (ctx->entries);
492 #  ifdef ACE_GETACL
493   free (ctx->ace_entries);
494 #  endif
495
496 # elif HAVE_GETACL /* HP-UX */
497
498 #  if HAVE_ACLV_H
499 #  endif
500
501 # elif HAVE_STATACL /* older AIX */
502
503 # elif HAVE_ACLSORT /* NonStop Kernel */
504
505 # endif
506 #endif
507 }