Lines 28-39
Link Here
|
28 |
# define S_ISLNK(Mode) 0 |
28 |
# define S_ISLNK(Mode) 0 |
29 |
#endif |
29 |
#endif |
30 |
|
30 |
|
|
|
31 |
#include "error.h" |
32 |
#include "quote.h" |
31 |
#include "acl.h" |
33 |
#include "acl.h" |
32 |
|
34 |
|
|
|
35 |
#ifdef HAVE_ACL_LIBACL_H |
36 |
# include <acl/libacl.h> |
37 |
#endif |
38 |
|
33 |
#include <errno.h> |
39 |
#include <errno.h> |
34 |
#ifndef ENOSYS |
40 |
#ifndef ENOSYS |
35 |
# define ENOSYS (-1) |
41 |
# define ENOSYS (-1) |
36 |
#endif |
42 |
#endif |
|
|
43 |
#ifndef ENOTSUP |
44 |
# define ENOTSUP (-1) |
45 |
#endif |
37 |
|
46 |
|
38 |
#if ENABLE_NLS |
47 |
#if ENABLE_NLS |
39 |
# include <libintl.h> |
48 |
# include <libintl.h> |
Lines 53-72
Link Here
|
53 |
int |
62 |
int |
54 |
file_has_acl (char const *path, struct stat const *pathstat) |
63 |
file_has_acl (char const *path, struct stat const *pathstat) |
55 |
{ |
64 |
{ |
56 |
/* FIXME: This implementation should work on recent-enough versions |
65 |
#if USE_ACL && HAVE_ACL && defined GETACLCNT |
57 |
of HP-UX, Solaris, and Unixware, but it simply returns 0 with |
66 |
/* This implementation should work on recent-enough versions of HP-UX, |
58 |
POSIX 1003.1e (draft 17 -- abandoned), AIX, GNU/Linux, Irix, and |
67 |
Solaris, and Unixware. */ |
59 |
Tru64. Please see Samba's source/lib/sysacls.c file for |
|
|
60 |
fix-related ideas. */ |
61 |
|
68 |
|
62 |
#if HAVE_ACL && defined GETACLCNT |
|
|
63 |
if (! S_ISLNK (pathstat->st_mode)) |
69 |
if (! S_ISLNK (pathstat->st_mode)) |
64 |
{ |
70 |
{ |
65 |
int n = acl (path, GETACLCNT, 0, NULL); |
71 |
int n = acl (path, GETACLCNT, 0, NULL); |
66 |
return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n); |
72 |
return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n); |
67 |
} |
73 |
} |
|
|
74 |
#elif USE_ACL && HAVE_ACL_EXTENDED_FILE |
75 |
/* Linux specific version. */ |
76 |
|
77 |
if (! S_ISLNK (pathstat->st_mode)) |
78 |
{ |
79 |
int ret = acl_extended_file (path); |
80 |
if (ret < 0) |
81 |
return (errno == ENOSYS || errno == ENOTSUP) ? 0 : -1; |
82 |
return ret; |
83 |
} |
68 |
#endif |
84 |
#endif |
69 |
|
85 |
|
|
|
86 |
/* FIXME: Add support for POSIX 1003.1e (draft 17 -- abandoned), AIX, Irix, |
87 |
and Tru64. Please see Samba's source/lib/sysacls.c file for fix-related |
88 |
ideas. */ |
89 |
|
70 |
return 0; |
90 |
return 0; |
71 |
} |
91 |
} |
72 |
|
92 |
|
Lines 76-93
Link Here
|
76 |
int |
96 |
int |
77 |
copy_acl (char const *src_path, char const *dst_path, mode_t mode) |
97 |
copy_acl (char const *src_path, char const *dst_path, mode_t mode) |
78 |
{ |
98 |
{ |
|
|
99 |
#if USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && \ |
100 |
HAVE_ACL_FREE && HAVE_ACL_ENTRIES |
101 |
/* Linux specific. Will work on all POSIX 1003.1e draft 17 (abandoned) |
102 |
systems if the Linux specific acl_entries() function is substituted. */ |
103 |
|
104 |
acl_t acl = acl_get_file (src_path, ACL_TYPE_ACCESS); |
105 |
if (acl == NULL) |
106 |
{ |
107 |
if (errno == ENOSYS || errno == ENOTSUP) |
108 |
return set_acl (dst_path, mode); |
109 |
else |
110 |
{ |
111 |
error (0, errno, "%s", quote (src_path)); |
112 |
return -1; |
113 |
} |
114 |
} |
115 |
|
116 |
if (acl_set_file (dst_path, ACL_TYPE_ACCESS, acl)) |
117 |
{ |
118 |
int saved_errno = errno; |
119 |
|
120 |
if (errno == ENOSYS || errno == ENOTSUP) |
121 |
{ |
122 |
int n = acl_entries (acl); |
123 |
|
124 |
acl_free (acl); |
125 |
if (n == 3) |
126 |
{ |
127 |
if (chmod (dst_path, mode)) |
128 |
saved_errno = errno; |
129 |
else |
130 |
return 0; |
131 |
} |
132 |
else |
133 |
chmod (dst_path, mode); |
134 |
} |
135 |
else |
136 |
{ |
137 |
acl_free (acl); |
138 |
chmod (dst_path, mode); |
139 |
} |
140 |
error (0, saved_errno, _("preserving permissions for %s"), |
141 |
quote (dst_path)); |
142 |
return -1; |
143 |
} |
144 |
else |
145 |
acl_free (acl); |
146 |
|
147 |
if (mode & (S_ISUID | S_ISGID | S_ISVTX)) |
148 |
{ |
149 |
/* We did not call chmod so far, so the special bits have not yet |
150 |
been set. */ |
151 |
|
152 |
if (chmod (dst_path, mode)) |
153 |
{ |
154 |
error (0, errno, _("preserving permissions for %s"), |
155 |
quote (dst_path)); |
156 |
return -1; |
157 |
} |
158 |
} |
159 |
|
160 |
if (S_ISDIR (mode)) |
161 |
{ |
162 |
acl = acl_get_file (src_path, ACL_TYPE_DEFAULT); |
163 |
if (acl == NULL) |
164 |
{ |
165 |
error (0, errno, "%s", quote (src_path)); |
166 |
return -1; |
167 |
} |
168 |
|
169 |
if (acl_set_file (dst_path, ACL_TYPE_DEFAULT, acl)) |
170 |
{ |
171 |
error (0, errno, _("preserving permissions for %s"), |
172 |
quote (dst_path)); |
173 |
acl_free(acl); |
174 |
return -1; |
175 |
} |
176 |
else |
177 |
acl_free(acl); |
178 |
} |
179 |
return 0; |
180 |
#else |
79 |
int ret = chmod (dst_path, mode); |
181 |
int ret = chmod (dst_path, mode); |
80 |
if (ret) |
182 |
if (ret) |
81 |
error (0, errno, _("preserving permissions for %s"), quote (dst_path)); |
183 |
error (0, errno, _("preserving permissions for %s"), quote (dst_path)); |
82 |
return ret; |
184 |
return ret; |
|
|
185 |
#endif |
83 |
} |
186 |
} |
84 |
|
187 |
|
85 |
/* Set the access control list of path to the permissions defined by mode. */ |
188 |
/* Set the access control list of path to the permissions defined by mode. */ |
86 |
int |
189 |
int |
87 |
set_acl (char const *path, mode_t mode) |
190 |
set_acl (char const *path, mode_t mode) |
88 |
{ |
191 |
{ |
|
|
192 |
#if USE_ACL && HAVE_ACL_FROM_TEXT && HAVE_ACL_SET_FILE && HAVE_ACL_FREE && \ |
193 |
HAVE_ACL_DELETE_DEF_FILE |
194 |
/* POSIX 1003.1e draft 17 (abandoned) specific version. */ |
195 |
|
196 |
char acl_text[] = "u::---,g::---,o::---"; |
197 |
acl_t acl; |
198 |
|
199 |
if (mode & S_IRUSR) acl_text[ 3] = 'r'; |
200 |
if (mode & S_IWUSR) acl_text[ 4] = 'w'; |
201 |
if (mode & S_IXUSR) acl_text[ 5] = 'x'; |
202 |
if (mode & S_IRGRP) acl_text[10] = 'r'; |
203 |
if (mode & S_IWGRP) acl_text[11] = 'w'; |
204 |
if (mode & S_IXGRP) acl_text[12] = 'x'; |
205 |
if (mode & S_IROTH) acl_text[17] = 'r'; |
206 |
if (mode & S_IWOTH) acl_text[18] = 'w'; |
207 |
if (mode & S_IXOTH) acl_text[19] = 'x'; |
208 |
|
209 |
acl = acl_from_text(acl_text); |
210 |
if (!acl) |
211 |
{ |
212 |
error (0, errno, "%s", quote (path)); |
213 |
return -1; |
214 |
} |
215 |
|
216 |
if (acl_set_file(path, ACL_TYPE_ACCESS, acl)) |
217 |
{ |
218 |
int saved_errno = errno; |
219 |
acl_free (acl); |
220 |
|
221 |
if (errno == ENOTSUP || errno == ENOSYS) |
222 |
{ |
223 |
if (chmod (path, mode)) |
224 |
saved_errno = errno; |
225 |
else |
226 |
return 0; |
227 |
} |
228 |
error (0, saved_errno, _("setting permissions for %s"), quote (path)); |
229 |
return -1; |
230 |
} |
231 |
else |
232 |
acl_free (acl); |
233 |
|
234 |
if (mode & (S_ISUID | S_ISGID | S_ISVTX)) |
235 |
{ |
236 |
/* We did not call chmod so far, so the special bits have not yet |
237 |
been set. */ |
238 |
|
239 |
if (chmod (path, mode)) |
240 |
{ |
241 |
error (0, errno, _("preserving permissions for %s"), |
242 |
quote (path)); |
243 |
return -1; |
244 |
} |
245 |
} |
246 |
|
247 |
if (S_ISDIR (mode) && acl_delete_def_file (path)) |
248 |
{ |
249 |
error (0, errno, _("setting permissions for %s"), quote (path)); |
250 |
return -1; |
251 |
} |
252 |
return 0; |
253 |
#else |
89 |
int ret = chmod (path, mode); |
254 |
int ret = chmod (path, mode); |
90 |
if (ret) |
255 |
if (ret) |
91 |
error (0, errno, _("setting permissions for %s"), quote (path)); |
256 |
error (0, errno, _("setting permissions for %s"), quote (path)); |
92 |
return ret; |
257 |
return ret; |
|
|
258 |
#endif |
93 |
} |
259 |
} |