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