2 * Copyright (c) 2003-2010 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "archive_platform.h"
28 __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 05:35:40Z kientzle $");
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
34 #define _ACL_PRIVATE /* For debugging */
38 #include <membership.h>
45 #include "archive_entry.h"
46 #include "archive_acl_private.h"
47 #include "archive_write_disk_private.h"
49 #if !HAVE_POSIX_ACL && !HAVE_NFS4_ACL
50 /* Default empty function body to satisfy mainline code. */
52 archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
53 struct archive_acl *abstract_acl)
56 (void)fd; /* UNUSED */
57 (void)name; /* UNUSED */
58 (void)abstract_acl; /* UNUSED */
62 #else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
65 #define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
67 #define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
68 #elif HAVE_ACL_TYPE_NFS4
69 #define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
72 static int set_acl(struct archive *, int fd, const char *,
74 acl_type_t, int archive_entry_acl_type, const char *tn);
77 archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
78 struct archive_acl *abstract_acl)
83 if ((archive_acl_types(abstract_acl)
84 & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
86 /* Solaris writes POSIX.1e access and default ACLs together */
87 ret = set_acl(a, fd, name, abstract_acl, ACLENT_T,
88 ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
89 #else /* HAVE_POSIX_ACL */
90 if ((archive_acl_types(abstract_acl)
91 & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
92 ret = set_acl(a, fd, name, abstract_acl,
93 ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
95 if (ret != ARCHIVE_OK)
98 if ((archive_acl_types(abstract_acl)
99 & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
100 ret = set_acl(a, fd, name, abstract_acl,
101 ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
103 #endif /* !HAVE_SUN_ACL */
104 /* Simultaneous POSIX.1e and NFSv4 is not supported */
107 #endif /* !HAVE_DARWIN_ACL */
109 if ((archive_acl_types(abstract_acl) &
110 ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
111 ret = set_acl(a, fd, name, abstract_acl,
112 ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
113 ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
115 #endif /* HAVE_NFS4_ACL */
120 * Translate system ACL permissions into libarchive internal structure
122 static const struct {
123 const int archive_perm;
124 const int platform_perm;
126 #if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
127 {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
128 {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
129 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
130 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
131 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
132 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
133 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
134 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
135 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
136 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
137 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
138 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
139 {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
140 {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
141 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
142 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
143 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
144 #elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
145 {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
146 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
147 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
148 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
149 {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
150 {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
151 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
152 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
153 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
154 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
155 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
156 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
157 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
158 {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
159 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
160 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
161 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
162 #else /* POSIX.1e ACL permissions */
163 {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
164 {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
165 {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
166 #if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
167 {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
168 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
169 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
170 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
171 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
172 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
173 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
174 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
175 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
176 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
177 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
178 {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
179 {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
180 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
181 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
182 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
184 #endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
189 * Translate system NFSv4 inheritance flags into libarchive internal structure
191 static const struct {
192 const int archive_inherit;
193 const int platform_inherit;
194 } acl_inherit_map[] = {
195 #if HAVE_SUN_ACL /* Solaris NFSv4 inheritance flags */
196 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
197 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
198 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
199 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
200 {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
201 {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
202 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
203 #elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
204 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
205 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
206 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
207 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
208 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
209 #else /* FreeBSD NFSv4 ACL inheritance flags */
210 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
211 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
212 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
213 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
214 {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
215 {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
216 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
217 #endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
219 #endif /* HAVE_NFS4_ACL */
222 set_acl(struct archive *a, int fd, const char *name,
223 struct archive_acl *abstract_acl,
224 acl_type_t acl_type, int ae_requested_type, const char *tname)
233 acl_entry_t acl_entry;
234 acl_permset_t acl_permset;
235 #if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
236 acl_flagset_t acl_flagset;
238 #endif /* HAVE_SUN_ACL */
239 #if HAVE_ACL_TYPE_NFS4
243 int ae_type, ae_permset, ae_tag, ae_id;
254 entries = archive_acl_reset(abstract_acl, ae_requested_type);
260 acl = malloc(sizeof(acl_t));
262 archive_set_error(a, ARCHIVE_ERRNO_MISC,
264 return (ARCHIVE_FAILED);
266 if (acl_type == ACE_T)
267 acl->acl_entry_size = sizeof(ace_t);
268 else if (acl_type == ACLENT_T)
269 acl->acl_entry_size = sizeof(aclent_t);
271 archive_set_error(a, ARCHIVE_ERRNO_MISC,
274 return (ARCHIVE_FAILED);
276 acl->acl_type = acl_type;
277 acl->acl_cnt = entries;
279 acl->acl_aclp = malloc(entries * acl->acl_entry_size);
280 if (acl->acl_aclp == NULL) {
281 archive_set_error(a, errno,
282 "Can't allocate memory for acl buffer");
284 return (ARCHIVE_FAILED);
286 #else /* !HAVE_SUN_ACL */
287 acl = acl_init(entries);
288 if (acl == (acl_t)NULL) {
289 archive_set_error(a, errno,
290 "Failed to initialize ACL working storage");
291 return (ARCHIVE_FAILED);
293 #endif /* !HAVE_SUN_ACL */
297 while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
298 &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
302 if (acl->acl_type == ACE_T) {
303 ace = &((ace_t *)acl->acl_aclp)[e];
305 ace->a_access_mask = 0;
308 aclent = &((aclent_t *)acl->acl_aclp)[e];
313 #else /* !HAVE_SUN_ACL */
316 * Mac OS doesn't support NFSv4 ACLs for
317 * owner@, group@ and everyone@.
318 * We skip any of these ACLs found.
320 if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
321 ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
322 ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
325 if (acl_create_entry(&acl, &acl_entry) != 0) {
326 archive_set_error(a, errno,
327 "Failed to create a new ACL entry");
328 ret = ARCHIVE_FAILED;
331 #endif /* !HAVE_SUN_ACL */
334 case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
335 acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
337 case ARCHIVE_ENTRY_ACL_TYPE_DENY:
338 acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
341 /* We don't support any other types on MacOS */
347 case ARCHIVE_ENTRY_ACL_USER:
348 ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
349 if (acl->acl_type == ACE_T)
352 aclent->a_id = ae_uid;
353 aclent->a_type |= USER;
356 case ARCHIVE_ENTRY_ACL_GROUP:
357 ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
358 if (acl->acl_type == ACE_T) {
360 ace->a_flags |= ACE_IDENTIFIER_GROUP;
362 aclent->a_id = ae_gid;
363 aclent->a_type |= GROUP;
366 case ARCHIVE_ENTRY_ACL_USER_OBJ:
367 if (acl->acl_type == ACE_T)
368 ace->a_flags |= ACE_OWNER;
370 aclent->a_type |= USER_OBJ;
372 case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
373 if (acl->acl_type == ACE_T) {
374 ace->a_flags |= ACE_GROUP;
375 ace->a_flags |= ACE_IDENTIFIER_GROUP;
377 aclent->a_type |= GROUP_OBJ;
379 case ARCHIVE_ENTRY_ACL_MASK:
380 aclent->a_type |= CLASS_OBJ;
382 case ARCHIVE_ENTRY_ACL_OTHER:
383 aclent->a_type |= OTHER_OBJ;
385 case ARCHIVE_ENTRY_ACL_EVERYONE:
386 ace->a_flags |= ACE_EVERYONE;
388 #else /* !HAVE_SUN_ACL */
389 case ARCHIVE_ENTRY_ACL_USER:
390 ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
391 #if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
392 acl_set_tag_type(acl_entry, ACL_USER);
393 acl_set_qualifier(acl_entry, &ae_uid);
395 if (mbr_identifier_to_uuid(ID_TYPE_UID, &ae_uid,
396 sizeof(uid_t), ae_uuid) != 0)
398 if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
400 #endif /* HAVE_DARWIN_ACL */
402 case ARCHIVE_ENTRY_ACL_GROUP:
403 ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
404 #if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
405 acl_set_tag_type(acl_entry, ACL_GROUP);
406 acl_set_qualifier(acl_entry, &ae_gid);
408 if (mbr_identifier_to_uuid(ID_TYPE_GID, &ae_gid,
409 sizeof(gid_t), ae_uuid) != 0)
411 if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
413 #endif /* HAVE_DARWIN_ACL */
415 #if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
416 case ARCHIVE_ENTRY_ACL_USER_OBJ:
417 acl_set_tag_type(acl_entry, ACL_USER_OBJ);
419 case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
420 acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
422 case ARCHIVE_ENTRY_ACL_MASK:
423 acl_set_tag_type(acl_entry, ACL_MASK);
425 case ARCHIVE_ENTRY_ACL_OTHER:
426 acl_set_tag_type(acl_entry, ACL_OTHER);
428 #if HAVE_ACL_TYPE_NFS4 /* FreeBSD only */
429 case ARCHIVE_ENTRY_ACL_EVERYONE:
430 acl_set_tag_type(acl_entry, ACL_EVERYONE);
433 #endif /* !HAVE_DARWIN_ACL */
434 #endif /* !HAVE_SUN_ACL */
436 archive_set_error(a, ARCHIVE_ERRNO_MISC,
438 ret = ARCHIVE_FAILED;
442 #if HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL
446 case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
448 ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
452 case ARCHIVE_ENTRY_ACL_TYPE_DENY:
454 ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
458 case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
460 ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
464 case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
466 ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
470 case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
474 case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
476 aclent->a_type |= ACL_DEFAULT;
480 #else /* !HAVE_SUN_ACL */
481 case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
482 r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
484 case ARCHIVE_ENTRY_ACL_TYPE_DENY:
485 r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
487 case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
488 r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
490 case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
491 r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM);
493 case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
494 case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
495 // These don't translate directly into the system ACL.
497 #endif /* !HAVE_SUN_ACL */
499 archive_set_error(a, ARCHIVE_ERRNO_MISC,
500 "Unknown ACL entry type");
501 ret = ARCHIVE_FAILED;
509 archive_set_error(a, errno,
510 "Failed to set ACL entry type");
511 ret = ARCHIVE_FAILED;
514 #endif /* HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL */
517 if (acl->acl_type == ACLENT_T) {
518 if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
520 if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
522 if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
526 if (acl_get_permset(acl_entry, &acl_permset) != 0) {
527 archive_set_error(a, errno,
528 "Failed to get ACL permission set");
529 ret = ARCHIVE_FAILED;
532 if (acl_clear_perms(acl_permset) != 0) {
533 archive_set_error(a, errno,
534 "Failed to clear ACL permissions");
535 ret = ARCHIVE_FAILED;
538 #endif /* !HAVE_SUN_ACL */
539 for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
540 if (ae_permset & acl_perm_map[i].archive_perm) {
542 ace->a_access_mask |=
543 acl_perm_map[i].platform_perm;
545 if (acl_add_perm(acl_permset,
546 acl_perm_map[i].platform_perm) != 0) {
547 archive_set_error(a, errno,
548 "Failed to add ACL permission");
549 ret = ARCHIVE_FAILED;
558 if (acl_type == ACE_T)
559 #elif HAVE_DARWIN_ACL
560 if (acl_type == ACL_TYPE_EXTENDED)
562 if (acl_type == ACL_TYPE_NFS4)
565 #if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
567 * acl_get_flagset_np() fails with non-NFSv4 ACLs
569 if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
570 archive_set_error(a, errno,
571 "Failed to get flagset from an NFSv4 ACL entry");
572 ret = ARCHIVE_FAILED;
575 if (acl_clear_flags_np(acl_flagset) != 0) {
576 archive_set_error(a, errno,
577 "Failed to clear flags from an NFSv4 ACL flagset");
578 ret = ARCHIVE_FAILED;
581 #endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
582 for (i = 0; i < (int)(sizeof(acl_inherit_map) /sizeof(acl_inherit_map[0])); ++i) {
583 if (ae_permset & acl_inherit_map[i].archive_inherit) {
586 acl_inherit_map[i].platform_inherit;
587 #else /* !HAVE_SUN_ACL */
588 if (acl_add_flag_np(acl_flagset,
589 acl_inherit_map[i].platform_inherit) != 0) {
590 archive_set_error(a, errno,
591 "Failed to add flag to NFSv4 ACL flagset");
592 ret = ARCHIVE_FAILED;
595 #endif /* HAVE_SUN_ACL */
599 #endif /* HAVE_NFS4_ACL */
605 #if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL
606 /* Try restoring the ACL through 'fd' if we can. */
607 #if HAVE_SUN_ACL || HAVE_ACL_SET_FD_NP
609 #else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
610 if (fd >= 0 && acl_type == ACL_TYPE_ACCESS)
614 if (facl_set(fd, acl) == 0)
615 #elif HAVE_ACL_SET_FD_NP
616 if (acl_set_fd_np(fd, acl, acl_type) == 0)
617 #else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
618 if (acl_set_fd(fd, acl) == 0)
622 if (errno == EOPNOTSUPP) {
623 /* Filesystem doesn't support ACLs */
626 archive_set_error(a, errno,
627 "Failed to set %s acl on fd", tname);
631 #endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
633 if (acl_set(name, acl) != 0)
634 #elif HAVE_ACL_SET_LINK_NP
635 if (acl_set_link_np(name, acl_type, acl) != 0)
637 /* TODO: Skip this if 'name' is a symlink. */
638 if (acl_set_file(name, acl_type, acl) != 0)
641 if (errno == EOPNOTSUPP) {
642 /* Filesystem doesn't support ACLs */
645 archive_set_error(a, errno, "Failed to set %s acl",
654 #endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */