acl_entry_get_perm(acl_entry_t aclent) #endif { int permset = 0; #if HAVE_POSIX_ACL acl_permset_t opaque_ps; #endif #if HAVE_SUN_ACL if (aclent->a_perm & 1) permset |= ARCHIVE_ENTRY_ACL_EXECUTE; if (aclent->a_perm & 2) permset |= ARCHIVE_ENTRY_ACL_WRITE; if (aclent->a_perm & 4) permset |= ARCHIVE_ENTRY_ACL_READ; #else /* translate the silly opaque permset to a bitmap */ acl_get_permset(aclent, &opaque_ps); if (ACL_GET_PERM(opaque_ps, ACL_EXECUTE)) permset |= ARCHIVE_ENTRY_ACL_EXECUTE; if (ACL_GET_PERM(opaque_ps, ACL_WRITE)) permset |= ARCHIVE_ENTRY_ACL_WRITE; if (ACL_GET_PERM(opaque_ps, ACL_READ)) permset |= ARCHIVE_ENTRY_ACL_READ; #endif return permset; }
/* * Translate POSIX.1e ACL into libarchive internal structure. */ static void setup_acl_posix1e(struct archive_read_disk *a, struct archive_entry *entry, acl_t acl, int archive_entry_acl_type) { acl_tag_t acl_tag; acl_entry_t acl_entry; acl_permset_t acl_permset; int s, ae_id, ae_tag, ae_perm; const char *ae_name; s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); while (s == 1) { ae_id = -1; ae_name = NULL; acl_get_tag_type(acl_entry, &acl_tag); if (acl_tag == ACL_USER) { ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry); ae_name = archive_read_disk_uname(&a->archive, ae_id); ae_tag = ARCHIVE_ENTRY_ACL_USER; } else if (acl_tag == ACL_GROUP) { ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry); ae_name = archive_read_disk_gname(&a->archive, ae_id); ae_tag = ARCHIVE_ENTRY_ACL_GROUP; } else if (acl_tag == ACL_MASK) { ae_tag = ARCHIVE_ENTRY_ACL_MASK; } else if (acl_tag == ACL_USER_OBJ) { ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; } else if (acl_tag == ACL_GROUP_OBJ) { ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; } else if (acl_tag == ACL_OTHER) { ae_tag = ARCHIVE_ENTRY_ACL_OTHER; } else { /* Skip types that libarchive can't support. */ continue; } acl_get_permset(acl_entry, &acl_permset); ae_perm = 0; /* * acl_get_perm() is spelled differently on different * platforms; see above. */ if (ACL_GET_PERM(acl_permset, ACL_EXECUTE)) ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE; if (ACL_GET_PERM(acl_permset, ACL_READ)) ae_perm |= ARCHIVE_ENTRY_ACL_READ; if (ACL_GET_PERM(acl_permset, ACL_WRITE)) ae_perm |= ARCHIVE_ENTRY_ACL_WRITE; archive_entry_acl_add_entry(entry, archive_entry_acl_type, ae_perm, ae_tag, ae_id, ae_name); s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); } }
static int translate_acl(struct archive_read_disk *a, struct archive_entry *entry, acl_t acl, int default_entry_acl_type) { acl_tag_t acl_tag; acl_entry_type_t acl_type; acl_flagset_t acl_flagset; acl_entry_t acl_entry; acl_permset_t acl_permset; int brand, i, r, entry_acl_type; int s, ae_id, ae_tag, ae_perm; const char *ae_name; // FreeBSD "brands" ACLs as POSIX.1e or NFSv4 // Make sure the "brand" on this ACL is consistent // with the default_entry_acl_type bits provided. acl_get_brand_np(acl, &brand); switch (brand) { case ACL_BRAND_POSIX: switch (default_entry_acl_type) { case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: break; default: // XXX set warning message? return ARCHIVE_FAILED; } break; case ACL_BRAND_NFS4: if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) { // XXX set warning message? return ARCHIVE_FAILED; } break; default: // XXX set warning message? return ARCHIVE_FAILED; break; } s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); while (s == 1) { ae_id = -1; ae_name = NULL; ae_perm = 0; acl_get_tag_type(acl_entry, &acl_tag); switch (acl_tag) { case ACL_USER: ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry); ae_name = archive_read_disk_uname(&a->archive, ae_id); ae_tag = ARCHIVE_ENTRY_ACL_USER; break; case ACL_GROUP: ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry); ae_name = archive_read_disk_gname(&a->archive, ae_id); ae_tag = ARCHIVE_ENTRY_ACL_GROUP; break; case ACL_MASK: ae_tag = ARCHIVE_ENTRY_ACL_MASK; break; case ACL_USER_OBJ: ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; break; case ACL_GROUP_OBJ: ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; break; case ACL_OTHER: ae_tag = ARCHIVE_ENTRY_ACL_OTHER; break; case ACL_EVERYONE: ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE; break; default: /* Skip types that libarchive can't support. */ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); continue; } // XXX acl type maps to allow/deny/audit/YYYY bits // XXX acl_get_entry_type_np on FreeBSD returns EINVAL for // non-NFSv4 ACLs entry_acl_type = default_entry_acl_type; r = acl_get_entry_type_np(acl_entry, &acl_type); if (r == 0) { switch (acl_type) { case ACL_ENTRY_TYPE_ALLOW: entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; break; case ACL_ENTRY_TYPE_DENY: entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; break; case ACL_ENTRY_TYPE_AUDIT: entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT; break; case ACL_ENTRY_TYPE_ALARM: entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; break; } } /* * Libarchive stores "flag" (NFSv4 inheritance bits) * in the ae_perm bitmap. */ acl_get_flagset_np(acl_entry, &acl_flagset); for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) { if (acl_get_flag_np(acl_flagset, acl_inherit_map[i].platform_inherit)) ae_perm |= acl_inherit_map[i].archive_inherit; } acl_get_permset(acl_entry, &acl_permset); for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) { /* * acl_get_perm() is spelled differently on different * platforms; see above. */ if (ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm)) ae_perm |= acl_perm_map[i].archive_perm; } archive_entry_acl_add_entry(entry, entry_acl_type, ae_perm, ae_tag, ae_id, ae_name); s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); } return (ARCHIVE_OK); }