(root)/
tar-1.35/
gnu/
acl-internal.h
       1  /* Internal implementation of access control lists.  -*- coding: utf-8 -*-
       2  
       3     Copyright (C) 2002-2003, 2005-2023 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 <https://www.gnu.org/licenses/>.
      17  
      18     Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible.  */
      19  
      20  /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, _GL_ATTRIBUTE_PURE.  */
      21  #if !_GL_CONFIG_H_INCLUDED
      22   #error "Please include config.h first."
      23  #endif
      24  
      25  #include "acl.h"
      26  
      27  #include <stdlib.h>
      28  
      29  /* All systems define the ACL related API in <sys/acl.h>.  */
      30  #if HAVE_SYS_ACL_H
      31  # include <sys/acl.h>
      32  #endif
      33  #if defined HAVE_FACL && ! defined GETACLCNT && defined ACL_CNT
      34  # define GETACLCNT ACL_CNT
      35  #endif
      36  
      37  /* On Linux and Cygwin >= 2.5, additional ACL related API is available in
      38     <acl/libacl.h>.  */
      39  #ifdef HAVE_ACL_LIBACL_H
      40  # include <acl/libacl.h>
      41  #endif
      42  
      43  /* On HP-UX >= 11.11, additional ACL API is available in <aclv.h>.  */
      44  #if HAVE_ACLV_H
      45  # include <sys/types.h>
      46  # include <aclv.h>
      47  /* HP-UX 11.11 lacks these declarations.  */
      48  extern int acl (char *, int, int, struct acl *);
      49  extern int aclsort (int, int, struct acl *);
      50  #endif
      51  
      52  #include <errno.h>
      53  
      54  #include <limits.h>
      55  #ifndef MIN
      56  # define MIN(a,b) ((a) < (b) ? (a) : (b))
      57  #endif
      58  
      59  #ifndef SIZE_MAX
      60  # define SIZE_MAX ((size_t) -1)
      61  #endif
      62  
      63  #ifndef HAVE_FCHMOD
      64  # define HAVE_FCHMOD false
      65  # define fchmod(fd, mode) (-1)
      66  #endif
      67  
      68  _GL_INLINE_HEADER_BEGIN
      69  #ifndef ACL_INTERNAL_INLINE
      70  # define ACL_INTERNAL_INLINE _GL_INLINE
      71  #endif
      72  
      73  #if USE_ACL
      74  
      75  # if HAVE_ACL_GET_FILE
      76  /* POSIX 1003.1e (draft 17 -- abandoned) specific version.  */
      77  /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
      78  
      79  #  ifndef MIN_ACL_ENTRIES
      80  #   define MIN_ACL_ENTRIES 4
      81  #  endif
      82  
      83  /* POSIX 1003.1e (draft 17) */
      84  #  ifdef HAVE_ACL_GET_FD
      85  /* Most platforms have a 1-argument acl_get_fd, only OSF/1 has a 2-argument
      86     macro(!).  */
      87  #   if HAVE_ACL_FREE_TEXT /* OSF/1 */
      88  ACL_INTERNAL_INLINE acl_t
      89  rpl_acl_get_fd (int fd)
      90  {
      91    return acl_get_fd (fd, ACL_TYPE_ACCESS);
      92  }
      93  #    undef acl_get_fd
      94  #    define acl_get_fd rpl_acl_get_fd
      95  #   endif
      96  #  else
      97  #   define HAVE_ACL_GET_FD false
      98  #   undef acl_get_fd
      99  #   define acl_get_fd(fd) (NULL)
     100  #  endif
     101  
     102  /* POSIX 1003.1e (draft 17) */
     103  #  ifdef HAVE_ACL_SET_FD
     104  /* Most platforms have a 2-argument acl_set_fd, only OSF/1 has a 3-argument
     105     macro(!).  */
     106  #   if HAVE_ACL_FREE_TEXT /* OSF/1 */
     107  ACL_INTERNAL_INLINE int
     108  rpl_acl_set_fd (int fd, acl_t acl)
     109  {
     110    return acl_set_fd (fd, ACL_TYPE_ACCESS, acl);
     111  }
     112  #    undef acl_set_fd
     113  #    define acl_set_fd rpl_acl_set_fd
     114  #   endif
     115  #  else
     116  #   define HAVE_ACL_SET_FD false
     117  #   undef acl_set_fd
     118  #   define acl_set_fd(fd, acl) (-1)
     119  #  endif
     120  
     121  /* POSIX 1003.1e (draft 13) */
     122  #  if ! HAVE_ACL_FREE_TEXT
     123  #   define acl_free_text(buf) acl_free (buf)
     124  #  endif
     125  
     126  /* Linux-specific */
     127  /* Cygwin >= 2.5 implements this function, but it returns 1 for all
     128     directories, thus is unusable.  */
     129  #  if !defined HAVE_ACL_EXTENDED_FILE || defined __CYGWIN__
     130  #   undef HAVE_ACL_EXTENDED_FILE
     131  #   define HAVE_ACL_EXTENDED_FILE false
     132  #   define acl_extended_file(name) (-1)
     133  #  endif
     134  
     135  #  if ! defined HAVE_ACL_FROM_MODE && ! defined HAVE_ACL_FROM_TEXT
     136  #   define acl_from_mode (NULL)
     137  #  endif
     138  
     139  /* Set to 0 if a file's mode is stored independently from the ACL.  */
     140  #  if (HAVE_ACL_COPY_EXT_NATIVE && HAVE_ACL_CREATE_ENTRY_NP) || defined __sgi /* Mac OS X, IRIX */
     141  #   define MODE_INSIDE_ACL 0
     142  #  endif
     143  
     144  /* Return the number of entries in ACL.
     145     Return -1 and set errno upon failure to determine it.  */
     146  /* Define a replacement for acl_entries if needed. (Only Linux has it.)  */
     147  #  if !HAVE_ACL_ENTRIES
     148  #   define acl_entries rpl_acl_entries
     149  extern int acl_entries (acl_t);
     150  #  endif
     151  
     152  #  if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
     153  /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
     154     Return 1 if the given ACL is non-trivial.
     155     Return 0 if it is trivial.  */
     156  extern int acl_extended_nontrivial (acl_t);
     157  #  else
     158  /* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
     159     Return 1 if the given ACL is non-trivial.
     160     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
     161     Return -1 and set errno upon failure to determine it.  */
     162  extern int acl_access_nontrivial (acl_t);
     163  
     164  /* ACL is an ACL, from a file, stored as type ACL_TYPE_DEFAULT.
     165     Return 1 if the given ACL is non-trivial.
     166     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
     167     Return -1 and set errno upon failure to determine it.  */
     168  extern int acl_default_nontrivial (acl_t);
     169  #  endif
     170  
     171  # elif HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */
     172  
     173  /* Set to 0 if a file's mode is stored independently from the ACL.  */
     174  #  if defined __CYGWIN__ /* Cygwin */
     175  #   define MODE_INSIDE_ACL 0
     176  #  endif
     177  
     178  /* Return 1 if the given ACL is non-trivial.
     179     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
     180  extern int acl_nontrivial (int count, aclent_t *entries) _GL_ATTRIBUTE_PURE;
     181  
     182  #  ifdef ACE_GETACL /* Solaris 10 */
     183  
     184  /* Test an ACL retrieved with ACE_GETACL.
     185     Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
     186     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
     187  extern int acl_ace_nontrivial (int count, ace_t *entries) _GL_ATTRIBUTE_PURE;
     188  
     189  /* Definitions for when the built executable is executed on Solaris 10
     190     (newer version) or Solaris 11.  */
     191  /* For a_type.  */
     192  #   define OLD_ALLOW 0
     193  #   define OLD_DENY  1
     194  #   define NEW_ACE_ACCESS_ALLOWED_ACE_TYPE 0 /* replaces ALLOW */
     195  #   define NEW_ACE_ACCESS_DENIED_ACE_TYPE  1 /* replaces DENY */
     196  /* For a_flags.  */
     197  #   define OLD_ACE_OWNER            0x0100
     198  #   define OLD_ACE_GROUP            0x0200
     199  #   define OLD_ACE_OTHER            0x0400
     200  #   define NEW_ACE_OWNER            0x1000
     201  #   define NEW_ACE_GROUP            0x2000
     202  #   define NEW_ACE_IDENTIFIER_GROUP 0x0040
     203  #   define NEW_ACE_EVERYONE         0x4000
     204  /* For a_access_mask.  */
     205  #   define NEW_ACE_READ_DATA         0x001 /* corresponds to 'r' */
     206  #   define NEW_ACE_WRITE_DATA        0x002 /* corresponds to 'w' */
     207  #   define NEW_ACE_APPEND_DATA       0x004
     208  #   define NEW_ACE_READ_NAMED_ATTRS  0x008
     209  #   define NEW_ACE_WRITE_NAMED_ATTRS 0x010
     210  #   define NEW_ACE_EXECUTE           0x020
     211  #   define NEW_ACE_DELETE_CHILD      0x040
     212  #   define NEW_ACE_READ_ATTRIBUTES   0x080
     213  #   define NEW_ACE_WRITE_ATTRIBUTES  0x100
     214  #   define NEW_ACE_DELETE          0x10000
     215  #   define NEW_ACE_READ_ACL        0x20000
     216  #   define NEW_ACE_WRITE_ACL       0x40000
     217  #   define NEW_ACE_WRITE_OWNER     0x80000
     218  #   define NEW_ACE_SYNCHRONIZE    0x100000
     219  
     220  #  endif
     221  
     222  # elif HAVE_GETACL /* HP-UX */
     223  
     224  /* Return 1 if the given ACL is non-trivial.
     225     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
     226  extern int acl_nontrivial (int count, struct acl_entry *entries);
     227  
     228  #  if HAVE_ACLV_H /* HP-UX >= 11.11 */
     229  
     230  /* Return 1 if the given ACL is non-trivial.
     231     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
     232  extern int aclv_nontrivial (int count, struct acl *entries);
     233  
     234  #  endif
     235  
     236  # elif HAVE_ACLX_GET && 0 /* AIX */
     237  
     238  /* TODO */
     239  
     240  # elif HAVE_STATACL /* older AIX */
     241  
     242  /* Return 1 if the given ACL is non-trivial.
     243     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
     244  extern int acl_nontrivial (struct acl *a);
     245  
     246  # elif HAVE_ACLSORT /* NonStop Kernel */
     247  
     248  /* Return 1 if the given ACL is non-trivial.
     249     Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
     250  extern int acl_nontrivial (int count, struct acl *entries);
     251  
     252  # endif
     253  
     254  /* Set to 1 if a file's mode is implicit by the ACL.  */
     255  # ifndef MODE_INSIDE_ACL
     256  #  define MODE_INSIDE_ACL 1
     257  # endif
     258  
     259  #endif
     260  
     261  struct permission_context {
     262    mode_t mode;
     263  #if USE_ACL
     264  # if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
     265    acl_t acl;
     266  #  if !HAVE_ACL_TYPE_EXTENDED
     267    acl_t default_acl;
     268  #  endif
     269    bool acls_not_supported;
     270  
     271  # elif defined GETACL /* Solaris, Cygwin < 2.5 */
     272    int count;
     273    aclent_t *entries;
     274  #  ifdef ACE_GETACL
     275    int ace_count;
     276    ace_t *ace_entries;
     277  #  endif
     278  
     279  # elif HAVE_GETACL /* HP-UX */
     280    struct acl_entry entries[NACLENTRIES];
     281    int count;
     282  #  if HAVE_ACLV_H
     283    struct acl aclv_entries[NACLVENTRIES];
     284    int aclv_count;
     285  #  endif
     286  
     287  # elif HAVE_STATACL /* older AIX */
     288    union { struct acl a; char room[4096]; } u;
     289    bool have_u;
     290  
     291  # elif HAVE_ACLSORT /* NonStop Kernel */
     292    struct acl entries[NACLENTRIES];
     293    int count;
     294  
     295  # endif
     296  #endif
     297  };
     298  
     299  int get_permissions (const char *, int, mode_t, struct permission_context *);
     300  int set_permissions (struct permission_context *, const char *, int);
     301  void free_permission_context (struct permission_context *);
     302  
     303  _GL_INLINE_HEADER_END