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 ACL_TYPE_EXTENDED
66 #elif HAVE_FREEBSD_NFS4_ACL
67 #define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
70 static int set_acl(struct archive *, int fd, const char *,
75 int archive_entry_acl_type, const char *tn);
78 archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
79 struct archive_acl *abstract_acl)
84 if ((archive_acl_types(abstract_acl)
85 & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
87 /* Solaris writes POSIX.1e access and default ACLs together */
88 ret = set_acl(a, fd, name, abstract_acl,
89 ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
90 #else /* HAVE_POSIX_ACL */
91 if ((archive_acl_types(abstract_acl)
92 & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
93 ret = set_acl(a, fd, name, abstract_acl,
94 ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
96 if (ret != ARCHIVE_OK)
99 if ((archive_acl_types(abstract_acl)
100 & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
101 ret = set_acl(a, fd, name, abstract_acl,
102 ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
104 #endif /* !HAVE_SUN_ACL */
105 /* Simultaneous POSIX.1e and NFSv4 is not supported */
108 #endif /* !HAVE_DARWIN_ACL */
110 if ((archive_acl_types(abstract_acl) &
111 ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
112 ret = set_acl(a, fd, name, abstract_acl,
114 ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
116 ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
118 #endif /* HAVE_NFS4_ACL */
122 #if !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL
124 * Translate system ACL permissions into libarchive internal structure
126 static const struct {
127 const int archive_perm;
128 const int platform_perm;
130 #if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */
131 {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
132 {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
133 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
134 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
135 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
136 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
137 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
138 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
139 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
140 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
141 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
142 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
143 {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
144 {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
145 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
146 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
147 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
148 #elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
149 {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
150 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
151 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
152 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
153 {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
154 {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
155 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
156 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
157 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
158 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
159 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
160 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
161 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
162 {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
163 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
164 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
165 #if HAVE_DECL_ACL_SYNCHRONIZE
166 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
168 #else /* POSIX.1e ACL permissions */
169 {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
170 {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
171 {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
172 #if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFSv4 ACL permissions */
173 {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
174 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
175 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
176 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
177 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
178 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
179 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
180 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
181 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
182 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
183 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
184 {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
185 {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
186 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
187 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
188 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
190 #endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
192 #endif /* !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL */
196 * Translate system NFSv4 inheritance flags into libarchive internal structure
198 static const struct {
199 const int archive_inherit;
200 const int platform_inherit;
201 } acl_inherit_map[] = {
202 #if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 inheritance flags */
203 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
204 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
205 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
206 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
207 {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
208 {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
209 #ifdef ACE_INHERITED_ACE
210 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
212 #elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
213 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
214 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
215 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
216 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
217 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
218 #else /* FreeBSD NFSv4 ACL inheritance flags */
219 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
220 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
221 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
222 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
223 {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
224 {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
225 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
226 #endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
228 #endif /* HAVE_NFS4_ACL */
231 set_acl(struct archive *a, int fd, const char *name,
232 struct archive_acl *abstract_acl,
236 int ae_requested_type, const char *tname)
240 #if HAVE_SUN_NFS4_ACL
247 acl_entry_t acl_entry;
248 acl_permset_t acl_permset;
249 #if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
250 acl_flagset_t acl_flagset;
252 #endif /* HAVE_SUN_ACL */
253 #if HAVE_FREEBSD_NFS4_ACL
257 int ae_type, ae_permset, ae_tag, ae_id;
268 entries = archive_acl_reset(abstract_acl, ae_requested_type);
273 switch (ae_requested_type) {
274 case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
276 aclp = malloc(entries * sizeof(aclent_t));
278 #if HAVE_SUN_NFS4_ACL
279 case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
281 aclp = malloc(entries * sizeof(ace_t));
286 archive_set_error(a, errno, "Invalid ACL type");
287 return (ARCHIVE_FAILED);
291 archive_set_error(a, errno,
292 "Can't allocate memory for acl buffer");
293 return (ARCHIVE_FAILED);
295 #else /* !HAVE_SUN_ACL */
296 acl = acl_init(entries);
297 if (acl == (acl_t)NULL) {
298 archive_set_error(a, errno,
299 "Failed to initialize ACL working storage");
300 return (ARCHIVE_FAILED);
302 #endif /* !HAVE_SUN_ACL */
306 while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
307 &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
310 #if HAVE_SUN_NFS4_ACL
314 aclent = &((aclent_t *)aclp)[e];
319 #if HAVE_SUN_NFS4_ACL
320 else { /* cmd == ACE_SETACL */
321 ace = &((ace_t *)aclp)[e];
323 ace->a_access_mask = 0;
326 #endif /* HAVE_SUN_NFS4_ACL */
327 #else /* !HAVE_SUN_ACL */
330 * Mac OS doesn't support NFSv4 ACLs for
331 * owner@, group@ and everyone@.
332 * We skip any of these ACLs found.
334 if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
335 ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
336 ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
339 if (acl_create_entry(&acl, &acl_entry) != 0) {
340 archive_set_error(a, errno,
341 "Failed to create a new ACL entry");
342 ret = ARCHIVE_FAILED;
345 #endif /* !HAVE_SUN_ACL */
348 case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
349 acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
351 case ARCHIVE_ENTRY_ACL_TYPE_DENY:
352 acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
355 /* We don't support any other types on MacOS */
361 case ARCHIVE_ENTRY_ACL_USER:
362 ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
363 if (aclent != NULL) {
364 aclent->a_id = ae_uid;
365 aclent->a_type |= USER;
367 #if HAVE_SUN_NFS4_ACL
373 case ARCHIVE_ENTRY_ACL_GROUP:
374 ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
375 if (aclent != NULL) {
376 aclent->a_id = ae_gid;
377 aclent->a_type |= GROUP;
379 #if HAVE_SUN_NFS4_ACL
382 ace->a_flags |= ACE_IDENTIFIER_GROUP;
386 case ARCHIVE_ENTRY_ACL_USER_OBJ:
388 aclent->a_type |= USER_OBJ;
389 #if HAVE_SUN_NFS4_ACL
391 ace->a_flags |= ACE_OWNER;
395 case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
397 aclent->a_type |= GROUP_OBJ;
398 #if HAVE_SUN_NFS4_ACL
400 ace->a_flags |= ACE_GROUP;
401 ace->a_flags |= ACE_IDENTIFIER_GROUP;
406 case ARCHIVE_ENTRY_ACL_MASK:
408 aclent->a_type |= CLASS_OBJ;
410 case ARCHIVE_ENTRY_ACL_OTHER:
412 aclent->a_type |= OTHER_OBJ;
414 #if HAVE_SUN_NFS4_ACL
415 case ARCHIVE_ENTRY_ACL_EVERYONE:
417 ace->a_flags |= ACE_EVERYONE;
420 #else /* !HAVE_SUN_ACL */
421 case ARCHIVE_ENTRY_ACL_USER:
422 ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
423 #if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
424 acl_set_tag_type(acl_entry, ACL_USER);
425 acl_set_qualifier(acl_entry, &ae_uid);
427 if (mbr_identifier_to_uuid(ID_TYPE_UID, &ae_uid,
428 sizeof(uid_t), ae_uuid) != 0)
430 if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
432 #endif /* HAVE_DARWIN_ACL */
434 case ARCHIVE_ENTRY_ACL_GROUP:
435 ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
436 #if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
437 acl_set_tag_type(acl_entry, ACL_GROUP);
438 acl_set_qualifier(acl_entry, &ae_gid);
440 if (mbr_identifier_to_uuid(ID_TYPE_GID, &ae_gid,
441 sizeof(gid_t), ae_uuid) != 0)
443 if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
445 #endif /* HAVE_DARWIN_ACL */
447 #if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
448 case ARCHIVE_ENTRY_ACL_USER_OBJ:
449 acl_set_tag_type(acl_entry, ACL_USER_OBJ);
451 case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
452 acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
454 case ARCHIVE_ENTRY_ACL_MASK:
455 acl_set_tag_type(acl_entry, ACL_MASK);
457 case ARCHIVE_ENTRY_ACL_OTHER:
458 acl_set_tag_type(acl_entry, ACL_OTHER);
460 #if HAVE_FREEBSD_NFS4_ACL /* FreeBSD only */
461 case ARCHIVE_ENTRY_ACL_EVERYONE:
462 acl_set_tag_type(acl_entry, ACL_EVERYONE);
465 #endif /* !HAVE_DARWIN_ACL */
466 #endif /* !HAVE_SUN_ACL */
468 archive_set_error(a, ARCHIVE_ERRNO_MISC,
470 ret = ARCHIVE_FAILED;
474 #if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL
478 #if HAVE_SUN_NFS4_ACL
479 case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
481 ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
485 case ARCHIVE_ENTRY_ACL_TYPE_DENY:
487 ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
491 case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
493 ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
497 case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
499 ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
504 case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
508 case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
510 aclent->a_type |= ACL_DEFAULT;
514 #else /* !HAVE_SUN_ACL */
515 case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
516 r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
518 case ARCHIVE_ENTRY_ACL_TYPE_DENY:
519 r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
521 case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
522 r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
524 case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
525 r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM);
527 case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
528 case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
529 // These don't translate directly into the system ACL.
531 #endif /* !HAVE_SUN_ACL */
533 archive_set_error(a, ARCHIVE_ERRNO_MISC,
534 "Unsupported ACL entry type");
535 ret = ARCHIVE_FAILED;
543 archive_set_error(a, errno,
544 "Failed to set ACL entry type");
545 ret = ARCHIVE_FAILED;
548 #endif /* HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL */
551 if (aclent != NULL) {
552 if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
554 if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
556 if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
559 #if HAVE_SUN_NFS4_ACL
560 else /* falls through to for statement below, ace != NULL */
563 if (acl_get_permset(acl_entry, &acl_permset) != 0) {
564 archive_set_error(a, errno,
565 "Failed to get ACL permission set");
566 ret = ARCHIVE_FAILED;
569 if (acl_clear_perms(acl_permset) != 0) {
570 archive_set_error(a, errno,
571 "Failed to clear ACL permissions");
572 ret = ARCHIVE_FAILED;
575 #endif /* !HAVE_SUN_ACL */
576 #if HAVE_POSIX_ACL || HAVE_NFS4_ACL
577 for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
578 if (ae_permset & acl_perm_map[i].archive_perm) {
580 ace->a_access_mask |=
581 acl_perm_map[i].platform_perm;
583 if (acl_add_perm(acl_permset,
584 acl_perm_map[i].platform_perm) != 0) {
585 archive_set_error(a, errno,
586 "Failed to add ACL permission");
587 ret = ARCHIVE_FAILED;
593 #endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
596 #if HAVE_SUN_NFS4_ACL
598 #elif HAVE_DARWIN_ACL
599 if (acl_type == ACL_TYPE_EXTENDED)
601 if (acl_type == ACL_TYPE_NFS4)
604 #if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
606 * acl_get_flagset_np() fails with non-NFSv4 ACLs
608 if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
609 archive_set_error(a, errno,
610 "Failed to get flagset from an NFSv4 ACL entry");
611 ret = ARCHIVE_FAILED;
614 if (acl_clear_flags_np(acl_flagset) != 0) {
615 archive_set_error(a, errno,
616 "Failed to clear flags from an NFSv4 ACL flagset");
617 ret = ARCHIVE_FAILED;
620 #endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
621 for (i = 0; i < (int)(sizeof(acl_inherit_map) /sizeof(acl_inherit_map[0])); ++i) {
622 if (ae_permset & acl_inherit_map[i].archive_inherit) {
625 acl_inherit_map[i].platform_inherit;
626 #else /* !HAVE_SUN_ACL */
627 if (acl_add_flag_np(acl_flagset,
628 acl_inherit_map[i].platform_inherit) != 0) {
629 archive_set_error(a, errno,
630 "Failed to add flag to NFSv4 ACL flagset");
631 ret = ARCHIVE_FAILED;
634 #endif /* HAVE_SUN_ACL */
638 #endif /* HAVE_NFS4_ACL */
644 #if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL
645 /* Try restoring the ACL through 'fd' if we can. */
646 #if HAVE_SUN_ACL || HAVE_ACL_SET_FD_NP
648 #else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
649 if (fd >= 0 && acl_type == ACL_TYPE_ACCESS)
653 if (facl(fd, cmd, entries, aclp) == 0)
654 #elif HAVE_ACL_SET_FD_NP
655 if (acl_set_fd_np(fd, acl, acl_type) == 0)
656 #else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
657 if (acl_set_fd(fd, acl) == 0)
661 if (errno == EOPNOTSUPP) {
662 /* Filesystem doesn't support ACLs */
665 archive_set_error(a, errno,
666 "Failed to set %s acl on fd", tname);
670 #endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
672 if (acl(name, cmd, entries, aclp) != 0)
673 #elif HAVE_ACL_SET_LINK_NP
674 if (acl_set_link_np(name, acl_type, acl) != 0)
676 /* TODO: Skip this if 'name' is a symlink. */
677 if (acl_set_file(name, acl_type, acl) != 0)
680 if (errno == EOPNOTSUPP) {
681 /* Filesystem doesn't support ACLs */
684 archive_set_error(a, errno, "Failed to set %s acl",
697 #endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */