1 /* Internal implementation of access control lists. 2 3 Copyright (C) 2002-2003, 2005-2009 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 Grnbacher, and Bruno Haible. */ 19 20 #include "acl.h" 21 22 #include <stdbool.h> 23 #include <stdlib.h> 24 25 /* All systems define the ACL related API in <sys/acl.h>. */ 26 #if HAVE_SYS_ACL_H 27 # include <sys/acl.h> 28 #endif 29 #if defined HAVE_ACL && ! defined GETACLCNT && defined ACL_CNT 30 # define GETACLCNT ACL_CNT 31 #endif 32 33 /* On Linux, additional ACL related API is available in <acl/libacl.h>. */ 34 #ifdef HAVE_ACL_LIBACL_H 35 # include <acl/libacl.h> 36 #endif 37 38 #include "error.h" 39 #include "quote.h" 40 41 #include <errno.h> 42 #ifndef ENOSYS 43 # define ENOSYS (-1) 44 #endif 45 #ifndef ENOTSUP 46 # define ENOTSUP (-1) 47 #endif 48 49 #ifndef HAVE_FCHMOD 50 # define HAVE_FCHMOD false 51 # define fchmod(fd, mode) (-1) 52 #endif 53 54 55 #if USE_ACL 56 57 # if HAVE_ACL_GET_FILE 58 /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */ 59 /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */ 60 61 # ifndef MIN_ACL_ENTRIES 62 # define MIN_ACL_ENTRIES 4 63 # endif 64 65 /* POSIX 1003.1e (draft 17) */ 66 # ifdef HAVE_ACL_GET_FD 67 /* Most platforms have a 1-argument acl_get_fd, only OSF/1 has a 2-argument 68 macro(!). */ 69 # if HAVE_ACL_FREE_TEXT /* OSF/1 */ 70 static inline acl_t 71 rpl_acl_get_fd (int fd) 72 { 73 return acl_get_fd (fd, ACL_TYPE_ACCESS); 74 } 75 # undef acl_get_fd 76 # define acl_get_fd rpl_acl_get_fd 77 # endif 78 # else 79 # define HAVE_ACL_GET_FD false 80 # undef acl_get_fd 81 # define acl_get_fd(fd) (NULL) 82 # endif 83 84 /* POSIX 1003.1e (draft 17) */ 85 # ifdef HAVE_ACL_SET_FD 86 /* Most platforms have a 2-argument acl_set_fd, only OSF/1 has a 3-argument 87 macro(!). */ 88 # if HAVE_ACL_FREE_TEXT /* OSF/1 */ 89 static inline int 90 rpl_acl_set_fd (int fd, acl_t acl) 91 { 92 return acl_set_fd (fd, ACL_TYPE_ACCESS, acl); 93 } 94 # undef acl_set_fd 95 # define acl_set_fd rpl_acl_set_fd 96 # endif 97 # else 98 # define HAVE_ACL_SET_FD false 99 # undef acl_set_fd 100 # define acl_set_fd(fd, acl) (-1) 101 # endif 102 103 /* POSIX 1003.1e (draft 13) */ 104 # if ! HAVE_ACL_FREE_TEXT 105 # define acl_free_text(buf) acl_free (buf) 106 # endif 107 108 /* Linux-specific */ 109 # ifndef HAVE_ACL_EXTENDED_FILE 110 # define HAVE_ACL_EXTENDED_FILE false 111 # define acl_extended_file(name) (-1) 112 # endif 113 114 /* Linux-specific */ 115 # ifndef HAVE_ACL_FROM_MODE 116 # define HAVE_ACL_FROM_MODE false 117 # define acl_from_mode(mode) (NULL) 118 # endif 119 120 /* Set to 1 if a file's mode is implicit by the ACL. 121 Set to 0 if a file's mode is stored independently from the ACL. */ 122 # if HAVE_ACL_COPY_EXT_NATIVE && HAVE_ACL_CREATE_ENTRY_NP /* MacOS X */ 123 # define MODE_INSIDE_ACL 0 124 # else 125 # define MODE_INSIDE_ACL 1 126 # endif 127 128 # if defined __APPLE__ && defined __MACH__ /* MacOS X */ 129 # define ACL_NOT_WELL_SUPPORTED(Err) \ 130 ((Err) == ENOTSUP || (Err) == ENOSYS || (Err) == EINVAL || (Err) == EBUSY || (Err) == ENOENT) 131 # elif defined EOPNOTSUPP /* Tru64 NFS */ 132 # define ACL_NOT_WELL_SUPPORTED(Err) \ 133 ((Err) == ENOTSUP || (Err) == ENOSYS || (Err) == EINVAL || (Err) == EBUSY || (Err) == EOPNOTSUPP) 134 # else 135 # define ACL_NOT_WELL_SUPPORTED(Err) \ 136 ((Err) == ENOTSUP || (Err) == ENOSYS || (Err) == EINVAL || (Err) == EBUSY) 137 # endif 138 139 /* Return the number of entries in ACL. 140 Return -1 and set errno upon failure to determine it. */ 141 /* Define a replacement for acl_entries if needed. (Only Linux has it.) */ 142 # if !HAVE_ACL_ENTRIES 143 # define acl_entries rpl_acl_entries 144 extern int acl_entries (acl_t); 145 # endif 146 147 # if HAVE_ACL_TYPE_EXTENDED /* MacOS X */ 148 /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. 149 Return 1 if the given ACL is non-trivial. 150 Return 0 if it is trivial. */ 151 extern int acl_extended_nontrivial (acl_t); 152 # else 153 /* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS. 154 Return 1 if the given ACL is non-trivial. 155 Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. 156 Return -1 and set errno upon failure to determine it. */ 157 extern int acl_access_nontrivial (acl_t); 158 # endif 159 160 # elif HAVE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ 161 162 /* Set to 1 if a file's mode is implicit by the ACL. 163 Set to 0 if a file's mode is stored independently from the ACL. */ 164 # if defined __CYGWIN__ /* Cygwin */ 165 # define MODE_INSIDE_ACL 0 166 # else /* Solaris */ 167 # define MODE_INSIDE_ACL 1 168 # endif 169 170 # if !defined ACL_NO_TRIVIAL /* Solaris <= 10, Cygwin */ 171 172 /* Return 1 if the given ACL is non-trivial. 173 Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ 174 extern int acl_nontrivial (int count, aclent_t *entries); 175 176 # ifdef ACE_GETACL /* Solaris 10 */ 177 178 /* Test an ACL retrieved with ACE_GETACL. 179 Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. 180 Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ 181 extern int acl_ace_nontrivial (int count, ace_t *entries); 182 183 /* Definitions for when the built executable is executed on Solaris 10 184 (newer version) or Solaris 11. */ 185 /* For a_type. */ 186 # define ACE_ACCESS_ALLOWED_ACE_TYPE 0 /* replaces ALLOW */ 187 # define ACE_ACCESS_DENIED_ACE_TYPE 1 /* replaces DENY */ 188 /* For a_flags. */ 189 # define NEW_ACE_OWNER 0x1000 190 # define NEW_ACE_GROUP 0x2000 191 # define NEW_ACE_IDENTIFIER_GROUP 0x0040 192 # define ACE_EVERYONE 0x4000 193 /* For a_access_mask. */ 194 # define NEW_ACE_READ_DATA 0x001 /* corresponds to 'r' */ 195 # define NEW_ACE_WRITE_DATA 0x002 /* corresponds to 'w' */ 196 # define NEW_ACE_EXECUTE 0x004 /* corresponds to 'x' */ 197 198 # endif 199 200 # endif 201 202 # elif HAVE_GETACL /* HP-UX */ 203 204 /* Return 1 if the given ACL is non-trivial. 205 Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ 206 extern int acl_nontrivial (int count, struct acl_entry *entries, struct stat *sb); 207 208 # elif HAVE_ACLX_GET && 0 /* AIX */ 209 210 /* TODO */ 211 212 # elif HAVE_STATACL /* older AIX */ 213 214 /* Return 1 if the given ACL is non-trivial. 215 Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ 216 extern int acl_nontrivial (struct acl *a); 217 218 # endif 219 220 #endif 221