Add support for Solaris 7..10 ACLs.
[gnulib.git] / lib / acl-internal.h
1 /* Internal implementation of access control lists.
2
3    Copyright (C) 2002-2003, 2005-2008 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 and Andreas Gruenbacher.  */
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 #include "gettext.h"
50 #define _(msgid) gettext (msgid)
51
52 #ifndef HAVE_FCHMOD
53 # define HAVE_FCHMOD false
54 # define fchmod(fd, mode) (-1)
55 #endif
56
57
58 #if USE_ACL
59
60 # if HAVE_ACL_GET_FILE
61 /* POSIX 1003.1e (draft 17 -- abandoned) specific version.  */
62 /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */
63
64 #  ifndef MIN_ACL_ENTRIES
65 #   define MIN_ACL_ENTRIES 4
66 #  endif
67
68 /* POSIX 1003.1e (draft 17) */
69 #  ifdef HAVE_ACL_GET_FD
70 /* Most platforms have a 1-argument acl_get_fd, only OSF/1 has a 2-argument
71    macro(!).  */
72 #   if HAVE_ACL_FREE_TEXT /* OSF/1 */
73 static inline acl_t
74 rpl_acl_get_fd (int fd)
75 {
76   return acl_get_fd (fd, ACL_TYPE_ACCESS);
77 }
78 #    undef acl_get_fd
79 #    define acl_get_fd rpl_acl_get_fd
80 #   endif
81 #  else
82 #   define HAVE_ACL_GET_FD false
83 #   undef acl_get_fd
84 #   define acl_get_fd(fd) (NULL)
85 #  endif
86
87 /* POSIX 1003.1e (draft 17) */
88 #  ifdef HAVE_ACL_SET_FD
89 /* Most platforms have a 2-argument acl_set_fd, only OSF/1 has a 3-argument
90    macro(!).  */
91 #   if HAVE_ACL_FREE_TEXT /* OSF/1 */
92 static inline int
93 rpl_acl_set_fd (int fd, acl_t acl)
94 {
95   return acl_set_fd (fd, ACL_TYPE_ACCESS, acl);
96 }
97 #    undef acl_set_fd
98 #    define acl_set_fd rpl_acl_set_fd
99 #   endif
100 #  else
101 #   define HAVE_ACL_SET_FD false
102 #   undef acl_set_fd
103 #   define acl_set_fd(fd, acl) (-1)
104 #  endif
105
106 /* POSIX 1003.1e (draft 13) */
107 #  if ! HAVE_ACL_FREE_TEXT
108 #   define acl_free_text(buf) acl_free (buf)
109 #  endif
110
111 /* Linux-specific */
112 #  ifndef HAVE_ACL_EXTENDED_FILE
113 #   define HAVE_ACL_EXTENDED_FILE false
114 #   define acl_extended_file(name) (-1)
115 #  endif
116
117 /* Linux-specific */
118 #  ifndef HAVE_ACL_FROM_MODE
119 #   define HAVE_ACL_FROM_MODE false
120 #   define acl_from_mode(mode) (NULL)
121 #  endif
122
123 /* Set to 1 if a file's mode is implicit by the ACL.
124    Set to 0 if a file's mode is stored independently from the ACL.  */
125 #  if HAVE_ACL_COPY_EXT_NATIVE && HAVE_ACL_CREATE_ENTRY_NP /* MacOS X */
126 #   define MODE_INSIDE_ACL 0
127 #  else
128 #   define MODE_INSIDE_ACL 1
129 #  endif
130
131 #  if defined __APPLE__ && defined __MACH__ /* MacOS X */
132 #   define ACL_NOT_WELL_SUPPORTED(Err) \
133      ((Err) == ENOTSUP || (Err) == ENOSYS || (Err) == EINVAL || (Err) == EBUSY || (Err) == ENOENT)
134 #  elif defined EOPNOTSUPP /* Tru64 NFS */
135 #   define ACL_NOT_WELL_SUPPORTED(Err) \
136      ((Err) == ENOTSUP || (Err) == ENOSYS || (Err) == EINVAL || (Err) == EBUSY || (Err) == EOPNOTSUPP)
137 #  else
138 #   define ACL_NOT_WELL_SUPPORTED(Err) \
139      ((Err) == ENOTSUP || (Err) == ENOSYS || (Err) == EINVAL || (Err) == EBUSY)
140 #  endif
141
142 /* Define a replacement for acl_entries if needed. (Only Linux has it.)  */
143 #  if !HAVE_ACL_ENTRIES
144 #   define acl_entries rpl_acl_entries
145 extern int acl_entries (acl_t);
146 #  endif
147
148 #  if HAVE_ACL_TYPE_EXTENDED /* MacOS X */
149 /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
150    Return 1 if the given ACL is non-trivial.
151    Return 0 if it is trivial.  */
152 extern int acl_extended_nontrivial (acl_t);
153 #  else
154 /* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
155    Return 1 if the given ACL is non-trivial.
156    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
157    Return -1 and set errno upon failure to determine it.  */
158 extern int acl_access_nontrivial (acl_t);
159 #  endif
160
161 # elif HAVE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
162
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 extern int acl_nontrivial (int count, aclent_t *entries);
166
167 #  ifdef ACE_GETACL
168 /* Test an ACL retrieved with ACE_GETACL.
169    Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
170    Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
171 extern int acl_ace_nontrivial (int count, ace_t *entries);
172 #  endif
173
174 # endif
175
176 #endif