Mercurial > hg > octave-kai > gnulib-hg
annotate lib/set-mode-acl.c @ 10182:4a177f4b083f
Add support for HP-UX ACLs.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 08 Jun 2008 19:08:22 +0200 |
parents | 5282ccc922b9 |
children | e8efce9962b0 |
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 | |
18 Written by Paul Eggert and Andreas Gruenbacher. */ | |
19 | |
20 #include <config.h> | |
21 | |
22 #include "acl.h" | |
23 | |
24 #include "acl-internal.h" | |
25 | |
26 /* If DESC is a valid file descriptor use fchmod to change the | |
27 file's mode to MODE on systems that have fchown. On systems | |
28 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
|
29 NAME instead. |
7215efd0ff4f
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10168
diff
changeset
|
30 Return 0 if successful. Return -1 and set errno upon failure. */ |
10126 | 31 |
32 int | |
33 chmod_or_fchmod (const char *name, int desc, mode_t mode) | |
34 { | |
35 if (HAVE_FCHMOD && desc != -1) | |
36 return fchmod (desc, mode); | |
37 else | |
38 return chmod (name, mode); | |
39 } | |
40 | |
41 /* Set the access control lists of a file. If DESC is a valid file | |
42 descriptor, use file descriptor operations where available, else use | |
43 filename based operations on NAME. If access control lists are not | |
44 available, fchmod the target file to MODE. Also sets the | |
45 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
|
46 to those from MODE if any are set. |
0c9f7838132c
Document qset_acl return value precisely.
Bruno Haible <bruno@clisp.org>
parents:
10126
diff
changeset
|
47 Return 0 if successful. Return -1 and set errno upon failure. */ |
10126 | 48 |
49 int | |
50 qset_acl (char const *name, int desc, mode_t mode) | |
51 { | |
52 #if USE_ACL | |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
53 # if HAVE_ACL_GET_FILE |
10126 | 54 /* 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
|
55 /* 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
|
56 # if MODE_INSIDE_ACL |
10126 | 57 /* Linux, FreeBSD, IRIX, Tru64 */ |
58 | |
59 /* We must also have acl_from_text and acl_delete_def_file. | |
60 (acl_delete_def_file could be emulated with acl_init followed | |
61 by acl_set_file, but acl_set_file with an empty acl is | |
62 unspecified.) */ | |
63 | |
64 # ifndef HAVE_ACL_FROM_TEXT | |
65 # error Must have acl_from_text (see POSIX 1003.1e draft 17). | |
66 # endif | |
67 # ifndef HAVE_ACL_DELETE_DEF_FILE | |
68 # error Must have acl_delete_def_file (see POSIX 1003.1e draft 17). | |
69 # endif | |
70 | |
71 acl_t acl; | |
72 int ret; | |
73 | |
74 if (HAVE_ACL_FROM_MODE) /* Linux */ | |
75 { | |
76 acl = acl_from_mode (mode); | |
77 if (!acl) | |
78 return -1; | |
79 } | |
80 else /* FreeBSD, IRIX, Tru64 */ | |
81 { | |
82 /* If we were to create the ACL using the functions acl_init(), | |
83 acl_create_entry(), acl_set_tag_type(), acl_set_qualifier(), | |
84 acl_get_permset(), acl_clear_perm[s](), acl_add_perm(), we | |
85 would need to create a qualifier. I don't know how to do this. | |
86 So create it using acl_from_text(). */ | |
87 | |
88 # if HAVE_ACL_FREE_TEXT /* Tru64 */ | |
89 char acl_text[] = "u::---,g::---,o::---,"; | |
90 # else /* FreeBSD, IRIX */ | |
91 char acl_text[] = "u::---,g::---,o::---"; | |
92 # endif | |
93 | |
94 if (mode & S_IRUSR) acl_text[ 3] = 'r'; | |
95 if (mode & S_IWUSR) acl_text[ 4] = 'w'; | |
96 if (mode & S_IXUSR) acl_text[ 5] = 'x'; | |
97 if (mode & S_IRGRP) acl_text[10] = 'r'; | |
98 if (mode & S_IWGRP) acl_text[11] = 'w'; | |
99 if (mode & S_IXGRP) acl_text[12] = 'x'; | |
100 if (mode & S_IROTH) acl_text[17] = 'r'; | |
101 if (mode & S_IWOTH) acl_text[18] = 'w'; | |
102 if (mode & S_IXOTH) acl_text[19] = 'x'; | |
103 | |
104 acl = acl_from_text (acl_text); | |
105 if (!acl) | |
106 return -1; | |
107 } | |
108 if (HAVE_ACL_SET_FD && desc != -1) | |
109 ret = acl_set_fd (desc, acl); | |
110 else | |
111 ret = acl_set_file (name, ACL_TYPE_ACCESS, acl); | |
112 if (ret != 0) | |
113 { | |
114 int saved_errno = errno; | |
115 acl_free (acl); | |
116 | |
117 if (ACL_NOT_WELL_SUPPORTED (errno)) | |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
118 return chmod_or_fchmod (name, desc, mode); |
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
119 else |
10126 | 120 { |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
121 errno = saved_errno; |
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
122 return -1; |
10126 | 123 } |
124 } | |
125 else | |
126 acl_free (acl); | |
127 | |
128 if (S_ISDIR (mode) && acl_delete_def_file (name)) | |
129 return -1; | |
130 | |
131 if (mode & (S_ISUID | S_ISGID | S_ISVTX)) | |
132 { | |
133 /* We did not call chmod so far, so the special bits have not yet | |
134 been set. */ | |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
135 return chmod_or_fchmod (name, desc, mode); |
10126 | 136 } |
137 return 0; | |
138 | |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
139 # else /* !MODE_INSIDE_ACL */ |
10126 | 140 /* MacOS X */ |
141 | |
10172
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
142 # if !HAVE_ACL_TYPE_EXTENDED |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
143 # error Must have ACL_TYPE_EXTENDED |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
144 # endif |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
145 |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
146 /* 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
|
147 and acl_get_file (name, ACL_TYPE_DEFAULT) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
148 always return NULL / EINVAL. You have to use |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
149 acl_get_file (name, ACL_TYPE_EXTENDED) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
150 or acl_get_fd (open (name, ...)) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
151 to retrieve an ACL. |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
152 On the other hand, |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
153 acl_set_file (name, ACL_TYPE_ACCESS, acl) |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
154 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
|
155 have the same effect as |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
156 acl_set_file (name, ACL_TYPE_EXTENDED, acl): |
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
157 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
|
158 |
10126 | 159 acl_t acl; |
160 int ret; | |
161 | |
162 /* Remove the ACL if the file has ACLs. */ | |
163 if (HAVE_ACL_GET_FD && desc != -1) | |
164 acl = acl_get_fd (desc); | |
165 else | |
10172
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
166 acl = acl_get_file (name, ACL_TYPE_EXTENDED); |
10126 | 167 if (acl) |
168 { | |
10171
f988df7e273d
Fix memory leak introduced on 2008-05-22.
Bruno Haible <bruno@clisp.org>
parents:
10170
diff
changeset
|
169 acl_free (acl); |
f988df7e273d
Fix memory leak introduced on 2008-05-22.
Bruno Haible <bruno@clisp.org>
parents:
10170
diff
changeset
|
170 |
10170
75a6b6b966a8
Avoid needing to know the textual representation of an ACL when possible.
Bruno Haible <bruno@clisp.org>
parents:
10169
diff
changeset
|
171 acl = acl_init (0); |
10126 | 172 if (acl) |
173 { | |
174 if (HAVE_ACL_SET_FD && desc != -1) | |
175 ret = acl_set_fd (desc, acl); | |
176 else | |
10172
50e666f281ef
Add support for MacOS X ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10171
diff
changeset
|
177 ret = acl_set_file (name, ACL_TYPE_EXTENDED, acl); |
10126 | 178 if (ret != 0) |
179 { | |
180 int saved_errno = errno; | |
181 | |
182 acl_free (acl); | |
183 | |
184 if (ACL_NOT_WELL_SUPPORTED (saved_errno)) | |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
185 return chmod_or_fchmod (name, desc, mode); |
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
186 else |
10126 | 187 { |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
188 errno = saved_errno; |
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
189 return -1; |
10126 | 190 } |
191 } | |
10171
f988df7e273d
Fix memory leak introduced on 2008-05-22.
Bruno Haible <bruno@clisp.org>
parents:
10170
diff
changeset
|
192 acl_free (acl); |
10126 | 193 } |
194 } | |
195 | |
10176
43bafd6ea0d8
Trivial code simplifications.
Bruno Haible <bruno@clisp.org>
parents:
10172
diff
changeset
|
196 /* Since !MODE_INSIDE_ACL, we have to call chmod explicitly. */ |
10126 | 197 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
|
198 # endif |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
199 |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
200 # 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
|
201 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
202 # if defined ACL_NO_TRIVIAL |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
203 /* 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
|
204 <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
|
205 acl_fromtext, ...). */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
206 |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
207 acl_t *aclp; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
208 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
|
209 int ret; |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
210 int saved_errno; |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
211 |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
212 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
|
213 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
|
214 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
|
215 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
|
216 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
|
217 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
|
218 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
|
219 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
|
220 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
|
221 |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
222 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
|
223 { |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
224 errno = ENOMEM; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
225 return -1; |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
226 } |
10180
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
227 |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
228 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
|
229 saved_errno = errno; |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
230 acl_free (aclp); |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
231 if (ret < 0) |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
232 { |
10180
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
233 if (saved_errno == ENOSYS) |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
234 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
|
235 errno = saved_errno; |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
236 return -1; |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
237 } |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
238 |
10180
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
239 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
|
240 { |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
241 /* 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
|
242 been set. */ |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
243 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
|
244 } |
9f98a7fc375c
Fix bug with setuid modes in Solaris 10+ code.
Bruno Haible <bruno@clisp.org>
parents:
10179
diff
changeset
|
245 return 0; |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
246 |
10179
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
247 # else /* Solaris, Cygwin, general case */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
248 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
249 # ifdef ACE_GETACL |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
250 /* 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
|
251 file systems (whereas the other ones are used in UFS file systems). */ |
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 ace_t entries[3]; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
254 int ret; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
255 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
256 entries[0].a_type = ALLOW; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
257 entries[0].a_flags = ACE_OWNER; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
258 entries[0].a_who = 0; /* irrelevant */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
259 entries[0].a_access_mask = (mode >> 6) & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
260 entries[1].a_type = ALLOW; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
261 entries[1].a_flags = ACE_GROUP; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
262 entries[1].a_who = 0; /* irrelevant */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
263 entries[1].a_access_mask = (mode >> 3) & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
264 entries[2].a_type = ALLOW; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
265 entries[2].a_flags = ACE_OTHER; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
266 entries[2].a_who = 0; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
267 entries[2].a_access_mask = mode & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
268 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
269 if (desc != -1) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
270 ret = facl (desc, ACE_SETACL, sizeof (entries) / sizeof (aclent_t), entries); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
271 else |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
272 ret = acl (name, ACE_SETACL, sizeof (entries) / sizeof (aclent_t), entries); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
273 if (ret < 0 && errno != EINVAL && errno != ENOTSUP) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
274 { |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
275 if (errno == ENOSYS) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
276 return chmod_or_fchmod (name, desc, mode); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
277 return -1; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
278 } |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
279 } |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
280 # endif |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
281 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
282 { |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
283 aclent_t entries[3]; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
284 int ret; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
285 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
286 entries[0].a_type = USER_OBJ; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
287 entries[0].a_id = 0; /* irrelevant */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
288 entries[0].a_perm = (mode >> 6) & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
289 entries[1].a_type = GROUP_OBJ; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
290 entries[1].a_id = 0; /* irrelevant */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
291 entries[1].a_perm = (mode >> 3) & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
292 entries[2].a_type = OTHER_OBJ; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
293 entries[2].a_id = 0; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
294 entries[2].a_perm = mode & 7; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
295 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
296 if (desc != -1) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
297 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
|
298 else |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
299 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
|
300 if (ret < 0) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
301 { |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
302 if (errno == ENOSYS) |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
303 return chmod_or_fchmod (name, desc, mode); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
304 return -1; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
305 } |
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 |
10181
5282ccc922b9
Add support for Cygwin ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10180
diff
changeset
|
308 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
|
309 { |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
310 /* We did not call chmod so far, so the special bits have not yet |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
311 been set. */ |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
312 return chmod_or_fchmod (name, desc, mode); |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
313 } |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
314 return 0; |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
315 |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
316 # endif |
90f51b86b088
Add support for Solaris 7..10 ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10176
diff
changeset
|
317 |
10182
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
318 # elif HAVE_GETACL /* HP-UX */ |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
319 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
320 struct stat statbuf; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
321 struct acl_entry entries[3]; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
322 int ret; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
323 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
324 if (desc != -1) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
325 ret = fstat (desc, &statbuf); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
326 else |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
327 ret = stat (name, &statbuf); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
328 if (ret < 0) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
329 return -1; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
330 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
331 entries[0].uid = statbuf.st_uid; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
332 entries[0].gid = ACL_NSGROUP; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
333 entries[0].mode = (mode >> 6) & 7; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
334 entries[1].uid = ACL_NSUSER; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
335 entries[1].gid = statbuf.st_gid; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
336 entries[1].mode = (mode >> 3) & 7; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
337 entries[2].uid = ACL_NSUSER; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
338 entries[2].gid = ACL_NSGROUP; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
339 entries[2].mode = mode & 7; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
340 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
341 if (desc != -1) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
342 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
|
343 else |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
344 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
|
345 if (ret < 0) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
346 { |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
347 if (errno == ENOSYS || errno == EOPNOTSUPP) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
348 return chmod_or_fchmod (name, desc, mode); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
349 return -1; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
350 } |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
351 |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
352 if (mode & (S_ISUID | S_ISGID | S_ISVTX)) |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
353 { |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
354 /* 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
|
355 been set. */ |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
356 return chmod_or_fchmod (name, desc, mode); |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
357 } |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
358 return 0; |
4a177f4b083f
Add support for HP-UX ACLs.
Bruno Haible <bruno@clisp.org>
parents:
10181
diff
changeset
|
359 |
10155
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
360 # else /* Unknown flavor of ACLs */ |
3df501903792
Simplify #ifs. Put Solaris code after POSIX-like code.
Bruno Haible <bruno@clisp.org>
parents:
10150
diff
changeset
|
361 return chmod_or_fchmod (name, desc, mode); |
10126 | 362 # endif |
363 #else /* !USE_ACL */ | |
364 return chmod_or_fchmod (name, desc, mode); | |
365 #endif | |
366 } | |
367 | |
368 /* As with qset_acl, but also output a diagnostic on failure. */ | |
369 | |
370 int | |
371 set_acl (char const *name, int desc, mode_t mode) | |
372 { | |
373 int r = qset_acl (name, desc, mode); | |
374 if (r != 0) | |
375 error (0, errno, _("setting permissions for %s"), quote (name)); | |
376 return r; | |
377 } |