Mercurial > hg > octave-kai > gnulib-hg
annotate lib/set-mode-acl.c @ 10198:5056e8a13405
Include gettext.h only in those files that need it.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Wed, 11 Jun 2008 02:33:46 +0200 |
parents | ccfd3047da72 |
children | 2f987829cba7 |
rev | line source |
---|---|
10126 | 1 /* set-mode-acl.c - set access control list equivalent to a mode |
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 | |
10184 | 18 Written by Paul Eggert and Andreas Gruenbacher, and Bruno Haible. */ |
10126 | 19 |
20 #include <config.h> | |
21 | |
22 #include "acl.h" | |
23 | |
24 #include "acl-internal.h" | |
25 | |
10198
5056e8a13405
Include gettext.h only in those files that need it.
Bruno Haible <bruno@clisp.org>
parents:
10191
diff
changeset
|
26 #include "gettext.h" |
5056e8a13405
Include gettext.h only in those files that need it.
Bruno Haible <bruno@clisp.org>
parents:
10191
diff
changeset
|
27 #define _(msgid) gettext (msgid) |
5056e8a13405
Include gettext.h only in those files that need it.
Bruno Haible <bruno@clisp.org>
parents:
10191
diff
changeset
|
28 |
5056e8a13405
Include gettext.h only in those files that need it.
Bruno Haible <bruno@clisp.org>
parents:
10191
diff
changeset
|
29 |
10126 | 30 /* If DESC is a valid file descriptor use fchmod to change the |
31 file's mode to MODE on systems that have fchown. On systems | |
32 that don't have fchown and if DESC is invalid, use chown on | |
10169
7215efd0ff4f
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10168
diff
changeset
|
33 NAME instead. |
7215efd0ff4f
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10168
diff
changeset
|
34 Return 0 if successful. Return -1 and set errno upon failure. */ |
10126 | 35 |
36 int | |
37 chmod_or_fchmod (const char *name, int desc, mode_t mode) | |
38 { | |
39 if (HAVE_FCHMOD && desc != -1) | |
40 return fchmod (desc, mode); | |
41 else | |
42 return chmod (name, mode); | |
43 } | |
44 | |
45 /* Set the access control lists of a file. If DESC is a valid file | |
46 descriptor, use file descriptor operations where available, else use | |
47 filename based operations on NAME. If access control lists are not | |
48 available, fchmod the target file to MODE. Also sets the | |
49 non-permission bits of the destination file (S_ISUID, S_ISGID, S_ISVTX) | |
10150
0c9f7838132c
Document qset_acl return value precisely.
Bruno Haible <bruno@clisp.org>
parents:
10126
diff
changeset
|
50 to those from MODE if any are set. |
0c9f7838132c
Document qset_acl return value precisely.
Bruno Haible <bruno@clisp.org>
parents:
10126
diff
changeset
|
51 Return 0 if successful. Return -1 and set errno upon failure. */ |
10126 | 52 |
53 int | |
54 qset_acl (char const *name, int desc, mode_t mode) | |
55 { | |
56 #if USE_ACL | |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
57 # if HAVE_ACL_GET_FILE |
10126 | 58 /* POSIX 1003.1e draft 17 (abandoned) specific version. */ |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
59 /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */ |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
60 # if MODE_INSIDE_ACL |
10126 | 61 /* Linux, FreeBSD, IRIX, Tru64 */ |
62 | |
63 /* We must also have acl_from_text and acl_delete_def_file. | |
64 (acl_delete_def_file could be emulated with acl_init followed | |
65 by acl_set_file, but acl_set_file with an empty acl is | |
66 unspecified.) */ | |
67 | |
68 # ifndef HAVE_ACL_FROM_TEXT | |
69 # error Must have acl_from_text (see POSIX 1003.1e draft 17). | |
70 # endif | |
71 # ifndef HAVE_ACL_DELETE_DEF_FILE | |
72 # error Must have acl_delete_def_file (see POSIX 1003.1e draft 17). | |
73 # endif | |
74 | |
75 acl_t acl; | |
76 int ret; | |
77 | |
78 if (HAVE_ACL_FROM_MODE) /* Linux */ | |
79 { | |
80 acl = acl_from_mode (mode); | |
81 if (!acl) | |
82 return -1; | |
83 } | |
84 else /* FreeBSD, IRIX, Tru64 */ | |
85 { | |
86 /* If we were to create the ACL using the functions acl_init(), | |
87 acl_create_entry(), acl_set_tag_type(), acl_set_qualifier(), | |
88 acl_get_permset(), acl_clear_perm[s](), acl_add_perm(), we | |
89 would need to create a qualifier. I don't know how to do this. | |
90 So create it using acl_from_text(). */ | |
91 | |
92 # if HAVE_ACL_FREE_TEXT /* Tru64 */ | |
93 char acl_text[] = "u::---,g::---,o::---,"; | |
94 # else /* FreeBSD, IRIX */ | |
95 char acl_text[] = "u::---,g::---,o::---"; | |
96 # endif | |
97 | |
98 if (mode & S_IRUSR) acl_text[ 3] = 'r'; | |
99 if (mode & S_IWUSR) acl_text[ 4] = 'w'; | |
100 if (mode & S_IXUSR) acl_text[ 5] = 'x'; | |
101 if (mode & S_IRGRP) acl_text[10] = 'r'; | |
102 if (mode & S_IWGRP) acl_text[11] = 'w'; | |
103 if (mode & S_IXGRP) acl_text[12] = 'x'; | |
104 if (mode & S_IROTH) acl_text[17] = 'r'; | |
105 if (mode & S_IWOTH) acl_text[18] = 'w'; | |
106 if (mode & S_IXOTH) acl_text[19] = 'x'; | |
107 | |
108 acl = acl_from_text (acl_text); | |
109 if (!acl) | |
110 return -1; | |
111 } | |
112 if (HAVE_ACL_SET_FD && desc != -1) | |
113 ret = acl_set_fd (desc, acl); | |
114 else | |
115 ret = acl_set_file (name, ACL_TYPE_ACCESS, acl); | |
116 if (ret != 0) | |
117 { | |
118 int saved_errno = errno; | |
119 acl_free (acl); | |
120 | |
121 if (ACL_NOT_WELL_SUPPORTED (errno)) | |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
122 return chmod_or_fchmod (name, desc, mode); |
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
123 else |
10126 | 124 { |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
125 errno = saved_errno; |
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
126 return -1; |
10126 | 127 } |
128 } | |
129 else | |
130 acl_free (acl); | |
131 | |
132 if (S_ISDIR (mode) && acl_delete_def_file (name)) | |
133 return -1; | |
134 | |
135 if (mode & (S_ISUID | S_ISGID | S_ISVTX)) | |
136 { | |
137 /* We did not call chmod so far, so the special bits have not yet | |
10184 | 138 been set. */ |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
139 return chmod_or_fchmod (name, desc, mode); |
10126 | 140 } |
141 return 0; | |
142 | |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
143 # else /* !MODE_INSIDE_ACL */ |
10126 | 144 /* MacOS X */ |
145 | |
10172
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
146 # if !HAVE_ACL_TYPE_EXTENDED |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
147 # error Must have ACL_TYPE_EXTENDED |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
148 # endif |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
149 |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
150 /* On MacOS X, acl_get_file (name, ACL_TYPE_ACCESS) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
151 and acl_get_file (name, ACL_TYPE_DEFAULT) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
152 always return NULL / EINVAL. You have to use |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
153 acl_get_file (name, ACL_TYPE_EXTENDED) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
154 or acl_get_fd (open (name, ...)) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
155 to retrieve an ACL. |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
156 On the other hand, |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
157 acl_set_file (name, ACL_TYPE_ACCESS, acl) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
158 and acl_set_file (name, ACL_TYPE_DEFAULT, acl) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
159 have the same effect as |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
160 acl_set_file (name, ACL_TYPE_EXTENDED, acl): |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
161 Each of these calls sets the file's ACL. */ |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
162 |
10126 | 163 acl_t acl; |
164 int ret; | |
165 | |
166 /* Remove the ACL if the file has ACLs. */ | |
167 if (HAVE_ACL_GET_FD && desc != -1) | |
168 acl = acl_get_fd (desc); | |
169 else | |
10172
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
170 acl = acl_get_file (name, ACL_TYPE_EXTENDED); |
10126 | 171 if (acl) |
172 { | |
10171
f988df7e273d
Fix memory leak introduced on 2008-05-22.
Bruno Haible <bruno@clisp.org>
parents:
10170
diff
changeset
|
173 acl_free (acl); |
f988df7e273d
Fix memory leak introduced on 2008-05-22.
Bruno Haible <bruno@clisp.org>
parents:
10170
diff
changeset
|
174 |
10170
75a6b6b966a8
Avoid needing to know the textual representation of an ACL when possible.
Bruno Haible <bruno@clisp.org>
parents:
10169
diff
changeset
|
175 acl = acl_init (0); |
10126 | 176 if (acl) |
177 { | |
178 if (HAVE_ACL_SET_FD && desc != -1) | |
179 ret = acl_set_fd (desc, acl); | |
180 else | |
10172
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
181 ret = acl_set_file (name, ACL_TYPE_EXTENDED, acl); |
10126 | 182 if (ret != 0) |
183 { | |
184 int saved_errno = errno; | |
185 | |
186 acl_free (acl); | |
187 | |
188 if (ACL_NOT_WELL_SUPPORTED (saved_errno)) | |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
189 return chmod_or_fchmod (name, desc, mode); |
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
190 else |
10126 | 191 { |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
192 errno = saved_errno; |
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
193 return -1; |
10126 | 194 } |
195 } | |
10171
f988df7e273d
Fix memory leak introduced on 2008-05-22.
Bruno Haible <bruno@clisp.org>
parents:
10170
diff
changeset
|
196 acl_free (acl); |
10126 | 197 } |
198 } | |
199 | |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
200 /* Since !MODE_INSIDE_ACL, we have to call chmod explicitly. */ |
10126 | 201 return chmod_or_fchmod (name, desc, mode); |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
202 # endif |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
203 |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
204 # elif HAVE_ACL && defined GETACLCNT /* Solaris, Cygwin, not HP-UX */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
205 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
206 # if defined ACL_NO_TRIVIAL |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
207 /* Solaris 10 (newer version), which has additional API declared in |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
208 <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial, |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
209 acl_fromtext, ...). */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
210 |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
211 acl_t *aclp; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
212 char acl_text[] = "user::---,group::---,mask:---,other:---"; |
10180
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
213 int ret; |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
214 int saved_errno; |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
215 |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
216 if (mode & S_IRUSR) acl_text[ 6] = 'r'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
217 if (mode & S_IWUSR) acl_text[ 7] = 'w'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
218 if (mode & S_IXUSR) acl_text[ 8] = 'x'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
219 if (mode & S_IRGRP) acl_text[17] = acl_text[26] = 'r'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
220 if (mode & S_IWGRP) acl_text[18] = acl_text[27] = 'w'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
221 if (mode & S_IXGRP) acl_text[19] = acl_text[28] = 'x'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
222 if (mode & S_IROTH) acl_text[36] = 'r'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
223 if (mode & S_IWOTH) acl_text[37] = 'w'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
224 if (mode & S_IXOTH) acl_text[38] = 'x'; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
225 |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
226 if (acl_fromtext (acl_text, &aclp) != 0) |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
227 { |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
228 errno = ENOMEM; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
229 return -1; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
230 } |
10180
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
231 |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
232 ret = (desc < 0 ? acl_set (name, aclp) : facl_set (desc, aclp)); |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
233 saved_errno = errno; |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
234 acl_free (aclp); |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
235 if (ret < 0) |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
236 { |
10180
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
237 if (saved_errno == ENOSYS) |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
238 return chmod_or_fchmod (name, desc, mode); |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
239 errno = saved_errno; |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
240 return -1; |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
241 } |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
242 |
10180
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
243 if (mode & (S_ISUID | S_ISGID | S_ISVTX)) |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
244 { |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
245 /* We did not call chmod so far, so the special bits have not yet |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
246 been set. */ |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
247 return chmod_or_fchmod (name, desc, mode); |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
248 } |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
249 return 0; |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
250 |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
251 # else /* Solaris, Cygwin, general case */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
252 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
253 # ifdef ACE_GETACL |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
254 /* Solaris also has a different variant of ACLs, used in ZFS and NFSv4 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
255 file systems (whereas the other ones are used in UFS file systems). */ |
10191
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
256 |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
257 /* The flags in the ace_t structure changed in a binary incompatible way |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
258 when ACL_NO_TRIVIAL etc. were introduced in <sys/acl.h> version 1.15. |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
259 How to distinguish the two conventions at runtime? |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
260 We fetch the existing ACL. In the old convention, usually three ACEs have |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
261 a_flags = ACE_OWNER / ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400. |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
262 In the new convention, these values are not used. */ |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
263 int convention; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
264 |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
265 { |
10191
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
266 int count; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
267 ace_t *entries; |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
268 |
10191
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
269 for (;;) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
270 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
271 if (desc != -1) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
272 count = facl (desc, ACE_GETACLCNT, 0, NULL); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
273 else |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
274 count = acl (name, ACE_GETACLCNT, 0, NULL); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
275 if (count <= 0) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
276 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
277 convention = -1; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
278 break; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
279 } |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
280 entries = (ace_t *) malloc (count * sizeof (ace_t)); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
281 if (entries == NULL) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
282 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
283 errno = ENOMEM; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
284 return -1; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
285 } |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
286 if ((desc != -1 |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
287 ? facl (desc, ACE_GETACL, count, entries) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
288 : acl (name, ACE_GETACL, count, entries)) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
289 == count) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
290 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
291 int i; |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
292 |
10191
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
293 convention = 0; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
294 for (i = 0; i < count; i++) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
295 if (entries[i].a_flags & (ACE_OWNER | ACE_GROUP | ACE_OTHER)) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
296 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
297 convention = 1; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
298 break; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
299 } |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
300 free (entries); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
301 break; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
302 } |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
303 /* Huh? The number of ACL entries changed since the last call. |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
304 Repeat. */ |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
305 free (entries); |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
306 } |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
307 } |
10191
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
308 |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
309 if (convention >= 0) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
310 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
311 ace_t entries[3]; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
312 int ret; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
313 |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
314 if (convention) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
315 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
316 /* Running on Solaris 10. */ |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
317 entries[0].a_type = ALLOW; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
318 entries[0].a_flags = ACE_OWNER; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
319 entries[0].a_who = 0; /* irrelevant */ |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
320 entries[0].a_access_mask = (mode >> 6) & 7; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
321 entries[1].a_type = ALLOW; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
322 entries[1].a_flags = ACE_GROUP; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
323 entries[1].a_who = 0; /* irrelevant */ |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
324 entries[1].a_access_mask = (mode >> 3) & 7; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
325 entries[2].a_type = ALLOW; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
326 entries[2].a_flags = ACE_OTHER; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
327 entries[2].a_who = 0; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
328 entries[2].a_access_mask = mode & 7; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
329 } |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
330 else |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
331 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
332 /* Running on Solaris 10 (newer version) or Solaris 11. */ |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
333 entries[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
334 entries[0].a_flags = NEW_ACE_OWNER; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
335 entries[0].a_who = 0; /* irrelevant */ |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
336 entries[0].a_access_mask = |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
337 (mode & 0400 ? NEW_ACE_READ_DATA : 0) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
338 | (mode & 0200 ? NEW_ACE_WRITE_DATA : 0) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
339 | (mode & 0100 ? NEW_ACE_EXECUTE : 0); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
340 entries[1].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
341 entries[1].a_flags = NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
342 entries[1].a_who = 0; /* irrelevant */ |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
343 entries[1].a_access_mask = |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
344 (mode & 0040 ? NEW_ACE_READ_DATA : 0) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
345 | (mode & 0020 ? NEW_ACE_WRITE_DATA : 0) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
346 | (mode & 0010 ? NEW_ACE_EXECUTE : 0); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
347 entries[2].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
348 entries[2].a_flags = ACE_EVERYONE; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
349 entries[2].a_who = 0; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
350 entries[2].a_access_mask = |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
351 (mode & 0004 ? NEW_ACE_READ_DATA : 0) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
352 | (mode & 0002 ? NEW_ACE_WRITE_DATA : 0) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
353 | (mode & 0001 ? NEW_ACE_EXECUTE : 0); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
354 } |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
355 if (desc != -1) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
356 ret = facl (desc, ACE_SETACL, |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
357 sizeof (entries) / sizeof (aclent_t), entries); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
358 else |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
359 ret = acl (name, ACE_SETACL, |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
360 sizeof (entries) / sizeof (aclent_t), entries); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
361 if (ret < 0 && errno != EINVAL && errno != ENOTSUP) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
362 { |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
363 if (errno == ENOSYS) |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
364 return chmod_or_fchmod (name, desc, mode); |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
365 return -1; |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
366 } |
ccfd3047da72
Work around the Solaris 10 ACE ACLs ABI change.
Bruno Haible <bruno@clisp.org>
parents:
10184
diff
changeset
|
367 } |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
368 # endif |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
369 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
370 { |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
371 aclent_t entries[3]; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
372 int ret; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
373 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
374 entries[0].a_type = USER_OBJ; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
375 entries[0].a_id = 0; /* irrelevant */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
376 entries[0].a_perm = (mode >> 6) & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
377 entries[1].a_type = GROUP_OBJ; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
378 entries[1].a_id = 0; /* irrelevant */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
379 entries[1].a_perm = (mode >> 3) & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
380 entries[2].a_type = OTHER_OBJ; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
381 entries[2].a_id = 0; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
382 entries[2].a_perm = mode & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
383 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
384 if (desc != -1) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
385 ret = facl (desc, SETACL, sizeof (entries) / sizeof (aclent_t), entries); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
386 else |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
387 ret = acl (name, SETACL, sizeof (entries) / sizeof (aclent_t), entries); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
388 if (ret < 0) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
389 { |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
390 if (errno == ENOSYS) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
391 return chmod_or_fchmod (name, desc, mode); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
392 return -1; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
393 } |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
394 } |
10184 | 395 |
10181
5282ccc922b9
Add support for Cygwin ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10180
diff
changeset
|
396 if (!MODE_INSIDE_ACL || (mode & (S_ISUID | S_ISGID | S_ISVTX))) |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
397 { |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
398 /* We did not call chmod so far, so the special bits have not yet |
10184 | 399 been set. */ |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
400 return chmod_or_fchmod (name, desc, mode); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
401 } |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
402 return 0; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
403 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
404 # endif |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
405 |
10182
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
406 # elif HAVE_GETACL /* HP-UX */ |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
407 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
408 struct stat statbuf; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
409 struct acl_entry entries[3]; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
410 int ret; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
411 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
412 if (desc != -1) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
413 ret = fstat (desc, &statbuf); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
414 else |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
415 ret = stat (name, &statbuf); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
416 if (ret < 0) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
417 return -1; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
418 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
419 entries[0].uid = statbuf.st_uid; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
420 entries[0].gid = ACL_NSGROUP; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
421 entries[0].mode = (mode >> 6) & 7; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
422 entries[1].uid = ACL_NSUSER; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
423 entries[1].gid = statbuf.st_gid; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
424 entries[1].mode = (mode >> 3) & 7; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
425 entries[2].uid = ACL_NSUSER; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
426 entries[2].gid = ACL_NSGROUP; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
427 entries[2].mode = mode & 7; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
428 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
429 if (desc != -1) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
430 ret = fsetacl (desc, sizeof (entries) / sizeof (struct acl_entry), entries); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
431 else |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
432 ret = setacl (name, sizeof (entries) / sizeof (struct acl_entry), entries); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
433 if (ret < 0) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
434 { |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
435 if (errno == ENOSYS || errno == EOPNOTSUPP) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
436 return chmod_or_fchmod (name, desc, mode); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
437 return -1; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
438 } |
10184 | 439 |
10182
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
440 if (mode & (S_ISUID | S_ISGID | S_ISVTX)) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
441 { |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
442 /* We did not call chmod so far, so the special bits have not yet |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
443 been set. */ |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
444 return chmod_or_fchmod (name, desc, mode); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
445 } |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
446 return 0; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
447 |
10183 | 448 # elif HAVE_ACLX_GET && 0 /* AIX */ |
449 | |
450 /* TODO: use aclx_fput or aclx_put, respectively */ | |
451 | |
452 # elif HAVE_STATACL /* older AIX */ | |
453 | |
454 union { struct acl a; char room[128]; } u; | |
455 int ret; | |
456 | |
457 u.a.acl_len = (char *) &u.a.acl_ext[0] - (char *) &u.a; /* no entries */ | |
458 u.a.acl_mode = mode & ~(S_IXACL | 0777); | |
459 u.a.u_access = (mode >> 6) & 7; | |
460 u.a.g_access = (mode >> 3) & 7; | |
461 u.a.o_access = mode & 7; | |
462 | |
463 if (desc != -1) | |
464 ret = fchacl (desc, &u.a, u.a.acl_len); | |
465 else | |
466 ret = chacl (name, &u.a, u.a.acl_len); | |
467 | |
468 if (ret < 0 && errno == ENOSYS) | |
469 return chmod_or_fchmod (name, desc, mode); | |
470 | |
471 return ret; | |
472 | |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
473 # else /* Unknown flavor of ACLs */ |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
474 return chmod_or_fchmod (name, desc, mode); |
10126 | 475 # endif |
476 #else /* !USE_ACL */ | |
477 return chmod_or_fchmod (name, desc, mode); | |
478 #endif | |
479 } | |
480 | |
481 /* As with qset_acl, but also output a diagnostic on failure. */ | |
482 | |
483 int | |
484 set_acl (char const *name, int desc, mode_t mode) | |
485 { | |
486 int r = qset_acl (name, desc, mode); | |
487 if (r != 0) | |
488 error (0, errno, _("setting permissions for %s"), quote (name)); | |
489 return r; | |
490 } |