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