test_acl_platform_nfs4.c revision 316337
1203955Srdivacky/*- 2198092Srdivacky * Copyright (c) 2003-2010 Tim Kientzle 3198092Srdivacky * Copyright (c) 2017 Martin Matuska 4198092Srdivacky * All rights reserved. 5198092Srdivacky * 6198092Srdivacky * Redistribution and use in source and binary forms, with or without 7198092Srdivacky * modification, are permitted provided that the following conditions 8198092Srdivacky * are met: 9239462Sdim * 1. Redistributions of source code must retain the above copyright 10239462Sdim * notice, this list of conditions and the following disclaimer. 11239462Sdim * 2. Redistributions in binary form must reproduce the above copyright 12239462Sdim * notice, this list of conditions and the following disclaimer in the 13239462Sdim * documentation and/or other materials provided with the distribution. 14198092Srdivacky * 15198092Srdivacky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16198092Srdivacky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17198092Srdivacky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18198092Srdivacky * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19198092Srdivacky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20198092Srdivacky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21198092Srdivacky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22249423Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23218893Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24206084Srdivacky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25198092Srdivacky */ 26198092Srdivacky#include "test.h" 27198092Srdivacky__FBSDID("$FreeBSD$"); 28198092Srdivacky 29206084Srdivacky#if ARCHIVE_ACL_NFS4 30234353Sdim#if HAVE_SYS_ACL_H 31234353Sdim#define _ACL_PRIVATE 32234353Sdim#include <sys/acl.h> 33234353Sdim#endif 34234353Sdim#if HAVE_SYS_RICHACL_H 35234353Sdim#include <sys/richacl.h> 36234353Sdim#endif 37234353Sdim#if HAVE_MEMBERSHIP_H 38198092Srdivacky#include <membership.h> 39234353Sdim#endif 40198092Srdivacky 41198092Srdivackystruct myacl_t { 42239462Sdim int type; 43198092Srdivacky int permset; 44239462Sdim int tag; 45198092Srdivacky int qual; /* GID or UID of user/group, depending on tag. */ 46198092Srdivacky const char *name; /* Name of user/group, depending on tag. */ 47234353Sdim}; 48198092Srdivacky 49234353Sdimstatic struct myacl_t acls_reg[] = { 50239462Sdim#if !ARCHIVE_ACL_DARWIN 51198092Srdivacky /* For this test, we need the file owner to be able to read and write the ACL. */ 52234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 53239462Sdim ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 54198092Srdivacky ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""}, 55198092Srdivacky#endif 56239462Sdim /* An entry for each type. */ 57239462Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 58198092Srdivacky ARCHIVE_ENTRY_ACL_USER, 108, "user108" }, 59234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, 60239462Sdim ARCHIVE_ENTRY_ACL_USER, 109, "user109" }, 61239462Sdim 62234353Sdim /* An entry for each permission. */ 63221345Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 64198092Srdivacky ARCHIVE_ENTRY_ACL_USER, 112, "user112" }, 65200583Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA, 66234353Sdim ARCHIVE_ENTRY_ACL_USER, 113, "user113" }, 67218893Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA, 68218893Sdim ARCHIVE_ENTRY_ACL_USER, 115, "user115" }, 69218893Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA, 70234353Sdim ARCHIVE_ENTRY_ACL_USER, 117, "user117" }, 71239462Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 72239462Sdim ARCHIVE_ENTRY_ACL_USER, 119, "user119" }, 73239462Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 74210299Sed ARCHIVE_ENTRY_ACL_USER, 120, "user120" }, 75234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 76239462Sdim ARCHIVE_ENTRY_ACL_USER, 122, "user122" }, 77239462Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 78234353Sdim ARCHIVE_ENTRY_ACL_USER, 123, "user123" }, 79198092Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE, 80198092Srdivacky ARCHIVE_ENTRY_ACL_USER, 124, "user124" }, 81234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, 82206084Srdivacky ARCHIVE_ENTRY_ACL_USER, 125, "user125" }, 83206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL, 84219077Sdim ARCHIVE_ENTRY_ACL_USER, 126, "user126" }, 85206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER, 86206084Srdivacky ARCHIVE_ENTRY_ACL_USER, 127, "user127" }, 87206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 88234353Sdim ARCHIVE_ENTRY_ACL_USER, 128, "user128" }, 89206084Srdivacky 90206084Srdivacky /* One entry for each qualifier. */ 91206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 92234353Sdim ARCHIVE_ENTRY_ACL_USER, 135, "user135" }, 93206084Srdivacky// { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 94206084Srdivacky// ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 95206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 96206084Srdivacky ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" }, 97234353Sdim#if !ARCHIVE_ACL_DARWIN 98206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 99206084Srdivacky ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 100206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 101234353Sdim ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } 102206084Srdivacky#else /* MacOS - mode 0654 */ 103206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, 104234353Sdim ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 105206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 106206084Srdivacky ARCHIVE_ENTRY_ACL_READ_DATA | 107206084Srdivacky ARCHIVE_ENTRY_ACL_WRITE_DATA | 108206084Srdivacky ARCHIVE_ENTRY_ACL_APPEND_DATA | 109206084Srdivacky ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 110206084Srdivacky ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | 111234353Sdim ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 112206084Srdivacky ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | 113206084Srdivacky ARCHIVE_ENTRY_ACL_READ_ACL | 114206084Srdivacky ARCHIVE_ENTRY_ACL_WRITE_ACL | 115234353Sdim ARCHIVE_ENTRY_ACL_WRITE_OWNER | 116206084Srdivacky ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 117205219Srdivacky ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 118205219Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 119205219Srdivacky ARCHIVE_ENTRY_ACL_READ_DATA | 120205219Srdivacky ARCHIVE_ENTRY_ACL_EXECUTE | 121239462Sdim ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 122198092Srdivacky ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 123234353Sdim ARCHIVE_ENTRY_ACL_READ_ACL | 124239462Sdim ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 125198092Srdivacky ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 126198092Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 127206084Srdivacky ARCHIVE_ENTRY_ACL_READ_DATA | 128206084Srdivacky ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 129234353Sdim ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 130206084Srdivacky ARCHIVE_ENTRY_ACL_READ_ACL | 131206084Srdivacky ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 132206084Srdivacky ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } 133206084Srdivacky#endif 134234353Sdim}; 135206084Srdivacky 136206084Srdivackystatic const int acls_reg_cnt = (int)(sizeof(acls_reg)/sizeof(acls_reg[0])); 137206084Srdivacky 138206084Srdivackystatic struct myacl_t acls_dir[] = { 139206084Srdivacky /* For this test, we need to be able to read and write the ACL. */ 140206084Srdivacky#if !ARCHIVE_ACL_DARWIN 141206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL, 142206084Srdivacky ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""}, 143234353Sdim#endif 144234353Sdim 145198092Srdivacky /* An entry for each type. */ 146206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 147234353Sdim ARCHIVE_ENTRY_ACL_USER, 101, "user101" }, 148234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 149234353Sdim ARCHIVE_ENTRY_ACL_USER, 102, "user102" }, 150234353Sdim 151234353Sdim /* An entry for each permission. */ 152234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 153234353Sdim ARCHIVE_ENTRY_ACL_USER, 201, "user201" }, 154234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE, 155234353Sdim ARCHIVE_ENTRY_ACL_USER, 202, "user202" }, 156234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, 157234353Sdim ARCHIVE_ENTRY_ACL_USER, 203, "user203" }, 158206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 159206084Srdivacky ARCHIVE_ENTRY_ACL_USER, 204, "user204" }, 160206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 161206084Srdivacky ARCHIVE_ENTRY_ACL_USER, 205, "user205" }, 162206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD, 163198092Srdivacky ARCHIVE_ENTRY_ACL_USER, 206, "user206" }, 164234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 165210299Sed ARCHIVE_ENTRY_ACL_USER, 207, "user207" }, 166198092Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 167206084Srdivacky ARCHIVE_ENTRY_ACL_USER, 208, "user208" }, 168198092Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE, 169234353Sdim ARCHIVE_ENTRY_ACL_USER, 209, "user209" }, 170198092Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, 171198092Srdivacky ARCHIVE_ENTRY_ACL_USER, 210, "user210" }, 172200583Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL, 173234353Sdim ARCHIVE_ENTRY_ACL_USER, 211, "user211" }, 174198092Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER, 175206084Srdivacky ARCHIVE_ENTRY_ACL_USER, 212, "user212" }, 176202379Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 177202379Srdivacky ARCHIVE_ENTRY_ACL_USER, 213, "user213" }, 178234353Sdim 179202379Srdivacky /* One entry with each inheritance value. */ 180206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 181202379Srdivacky ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 182234353Sdim ARCHIVE_ENTRY_ACL_USER, 301, "user301" }, 183202379Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 184234353Sdim ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, 185198092Srdivacky ARCHIVE_ENTRY_ACL_USER, 302, "user302" }, 186239462Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 187239462Sdim ARCHIVE_ENTRY_ACL_READ_DATA | 188239462Sdim ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT | 189239462Sdim ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, 190239462Sdim ARCHIVE_ENTRY_ACL_USER, 303, "user303" }, 191239462Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 192206084Srdivacky ARCHIVE_ENTRY_ACL_READ_DATA | 193206084Srdivacky ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT | 194234353Sdim ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, 195234353Sdim ARCHIVE_ENTRY_ACL_USER, 304, "user304" }, 196206084Srdivacky#if !defined(ARCHIVE_ACL_SUNOS_NFS4) || defined(ACE_INHERITED_ACE) 197200583Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 198206084Srdivacky ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, 199206084Srdivacky ARCHIVE_ENTRY_ACL_USER, 305, "user305" }, 200206084Srdivacky#endif 201206084Srdivacky 202206084Srdivacky#if 0 203206084Srdivacky /* FreeBSD does not support audit entries. */ 204249423Sdim { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 205249423Sdim ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, 206249423Sdim ARCHIVE_ENTRY_ACL_USER, 401, "user401" }, 207249423Sdim { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 208249423Sdim ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, 209249423Sdim ARCHIVE_ENTRY_ACL_USER, 402, "user402" }, 210249423Sdim#endif 211249423Sdim 212234353Sdim /* One entry for each qualifier. */ 213234353Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 214206084Srdivacky ARCHIVE_ENTRY_ACL_USER, 501, "user501" }, 215206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 216200583Srdivacky ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" }, 217206084Srdivacky#if !ARCHIVE_ACL_DARWIN 218198092Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 219234353Sdim ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 220226633Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 221218893Sdim ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } 222218893Sdim#else /* MacOS - mode 0654 */ 223218893Sdim { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, 224218893Sdim ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 225226633Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 226218893Sdim ARCHIVE_ENTRY_ACL_READ_DATA | 227218893Sdim ARCHIVE_ENTRY_ACL_WRITE_DATA | 228218893Sdim ARCHIVE_ENTRY_ACL_APPEND_DATA | 229218893Sdim ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 230234353Sdim ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | 231218893Sdim ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 232218893Sdim ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | 233218893Sdim ARCHIVE_ENTRY_ACL_READ_ACL | 234234353Sdim ARCHIVE_ENTRY_ACL_WRITE_ACL | 235218893Sdim ARCHIVE_ENTRY_ACL_WRITE_OWNER | 236218893Sdim ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 237218893Sdim ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 238218893Sdim { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 239234353Sdim ARCHIVE_ENTRY_ACL_READ_DATA | 240200583Srdivacky ARCHIVE_ENTRY_ACL_EXECUTE | 241200583Srdivacky ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 242200583Srdivacky ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 243206084Srdivacky ARCHIVE_ENTRY_ACL_READ_ACL | 244206084Srdivacky ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 245234353Sdim ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 246206084Srdivacky { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 247200583Srdivacky ARCHIVE_ENTRY_ACL_READ_DATA | 248206084Srdivacky ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 249200583Srdivacky ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 250200583Srdivacky ARCHIVE_ENTRY_ACL_READ_ACL | 251200583Srdivacky ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 252200583Srdivacky ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } 253200583Srdivacky#endif 254249423Sdim}; 255249423Sdim 256249423Sdimstatic const int acls_dir_cnt = (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); 257249423Sdim 258249423Sdimstatic void 259249423Sdimset_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end) 260249423Sdim{ 261249423Sdim int i; 262249423Sdim 263249423Sdim archive_entry_acl_clear(ae); 264249423Sdim#if !ARCHIVE_ACL_DARWIN 265249423Sdim if (start > 0) { 266249423Sdim assertEqualInt(ARCHIVE_OK, 267198092Srdivacky archive_entry_acl_add_entry(ae, 268206084Srdivacky acls[0].type, acls[0].permset, acls[0].tag, 269198092Srdivacky acls[0].qual, acls[0].name)); 270198092Srdivacky } 271239462Sdim#endif 272239462Sdim for (i = start; i < end; i++) { 273239462Sdim assertEqualInt(ARCHIVE_OK, 274239462Sdim archive_entry_acl_add_entry(ae, 275239462Sdim acls[i].type, acls[i].permset, acls[i].tag, 276239462Sdim acls[i].qual, acls[i].name)); 277198092Srdivacky } 278198092Srdivacky} 279226633Sdim 280206084Srdivackystatic int 281206084Srdivacky#if ARCHIVE_ACL_SUNOS_NFS4 282206084Srdivackyacl_permset_to_bitmap(uint32_t mask) 283206084Srdivacky#elif ARCHIVE_ACL_LIBRICHACL 284206084Srdivackyacl_permset_to_bitmap(unsigned int mask) 285206084Srdivacky#else 286206084Srdivackyacl_permset_to_bitmap(acl_permset_t opaque_ps) 287206084Srdivacky#endif 288206084Srdivacky{ 289226633Sdim static struct { int portable; int machine; } perms[] = { 290218893Sdim#ifdef ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL permissions */ 291218893Sdim {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE}, 292234353Sdim {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA}, 293218893Sdim {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY}, 294218893Sdim {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA}, 295218893Sdim {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE}, 296226633Sdim {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA}, 297218893Sdim {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY}, 298218893Sdim {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS}, 299218893Sdim {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS}, 300198092Srdivacky {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD}, 301198092Srdivacky {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES}, 302198092Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES}, 303234353Sdim {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE}, 304198092Srdivacky {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL}, 305198092Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL}, 306226633Sdim {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER}, 307226633Sdim {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE} 308218893Sdim#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL permissions */ 309218893Sdim {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, 310218893Sdim {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, 311226633Sdim {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, 312198092Srdivacky {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, 313234353Sdim {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, 314198092Srdivacky {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, 315198092Srdivacky {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, 316200583Srdivacky {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, 317234353Sdim {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, 318218893Sdim {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, 319234353Sdim {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, 320206084Srdivacky {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES}, 321198092Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES}, 322234353Sdim {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY}, 323239462Sdim {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY}, 324249423Sdim {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER}, 325239462Sdim#if HAVE_DECL_ACL_SYNCHRONIZE 326239462Sdim {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} 327239462Sdim#endif 328239462Sdim#elif ARCHIVE_ACL_LIBRICHACL 329239462Sdim {ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE}, 330239462Sdim {ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA}, 331239462Sdim {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY}, 332239462Sdim {ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA}, 333239462Sdim {ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE}, 334239462Sdim {ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA}, 335206084Srdivacky {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY}, 336206084Srdivacky {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS}, 337206084Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS}, 338206084Srdivacky {ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD}, 339206084Srdivacky {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES}, 340198092Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES}, 341234353Sdim {ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE}, 342206084Srdivacky {ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL}, 343234353Sdim {ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL}, 344198092Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER}, 345198092Srdivacky {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE} 346226633Sdim#else /* FreeBSD NFSv4 ACL permissions */ 347198092Srdivacky {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, 348198092Srdivacky {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, 349198893Srdivacky {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, 350198893Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, 351198893Srdivacky {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, 352226633Sdim {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, 353198893Srdivacky {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, 354198893Srdivacky {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, 355198893Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, 356198092Srdivacky {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, 357198893Srdivacky {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, 358226633Sdim {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, 359226633Sdim {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, 360198893Srdivacky {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL}, 361198893Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL}, 362198893Srdivacky {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER}, 363198893Srdivacky {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} 364226633Sdim#endif 365234353Sdim }; 366218893Sdim int i, permset = 0; 367218893Sdim 368218893Sdim for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i) 369234353Sdim#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL 370218893Sdim if (mask & perms[i].machine) 371198092Srdivacky#else 372210299Sed if (acl_get_perm_np(opaque_ps, perms[i].machine)) 373210299Sed#endif 374210299Sed permset |= perms[i].portable; 375210299Sed return permset; 376210299Sed} 377210299Sed 378198092Srdivackystatic int 379198092Srdivacky#if ARCHIVE_ACL_SUNOS_NFS4 380198092Srdivackyacl_flagset_to_bitmap(uint16_t flags) 381234353Sdim#elif ARCHIVE_ACL_LIBRICHACL 382198092Srdivackyacl_flagset_to_bitmap(int flags) 383206084Srdivacky#else 384206084Srdivackyacl_flagset_to_bitmap(acl_flagset_t opaque_fs) 385202379Srdivacky#endif 386202379Srdivacky{ 387234353Sdim static struct { int portable; int machine; } perms[] = { 388198092Srdivacky#if ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL inheritance flags */ 389198092Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE}, 390198092Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE}, 391198092Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE}, 392198092Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE}, 393198092Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, 394198092Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG}, 395234353Sdim#ifdef ACE_INHERITED_ACE 396218893Sdim {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE} 397218893Sdim#endif 398218893Sdim#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL inheritance flags */ 399198092Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, 400198092Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, 401206084Srdivacky {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, 402 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT}, 403 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT} 404#elif ARCHIVE_ACL_LIBRICHACL 405 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE}, 406 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE}, 407 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE}, 408 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE}, 409 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE} 410#else /* FreeBSD NFSv4 ACL inheritance flags */ 411 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, 412 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, 413 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, 414 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, 415 {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS}, 416 {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS}, 417 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY} 418#endif 419 }; 420 int i, flagset = 0; 421 422 for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i) 423#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL 424 if (flags & perms[i].machine) 425#else 426 if (acl_get_flag_np(opaque_fs, perms[i].machine)) 427#endif 428 flagset |= perms[i].portable; 429 return flagset; 430} 431 432#if ARCHIVE_ACL_SUNOS_NFS4 433static int 434acl_match(ace_t *ace, struct myacl_t *myacl) 435{ 436 int perms; 437 438 perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags); 439 440 if (perms != myacl->permset) 441 return (0); 442 443 switch (ace->a_type) { 444 case ACE_ACCESS_ALLOWED_ACE_TYPE: 445 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) 446 return (0); 447 break; 448 case ACE_ACCESS_DENIED_ACE_TYPE: 449 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) 450 return (0); 451 break; 452 case ACE_SYSTEM_AUDIT_ACE_TYPE: 453 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT) 454 return (0); 455 break; 456 case ACE_SYSTEM_ALARM_ACE_TYPE: 457 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM) 458 return (0); 459 break; 460 default: 461 return (0); 462 } 463 464 if (ace->a_flags & ACE_OWNER) { 465 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) 466 return (0); 467 } else if (ace->a_flags & ACE_GROUP) { 468 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) 469 return (0); 470 } else if (ace->a_flags & ACE_EVERYONE) { 471 if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) 472 return (0); 473 } else if (ace->a_flags & ACE_IDENTIFIER_GROUP) { 474 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 475 return (0); 476 if ((gid_t)myacl->qual != ace->a_who) 477 return (0); 478 } else { 479 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 480 return (0); 481 if ((uid_t)myacl->qual != ace->a_who) 482 return (0); 483 } 484 return (1); 485} 486#elif ARCHIVE_ACL_LIBRICHACL 487static int 488acl_match(struct richace *richace, struct myacl_t *myacl) 489{ 490 int perms; 491 492 perms = acl_permset_to_bitmap(richace->e_mask) | 493 acl_flagset_to_bitmap(richace->e_flags); 494 495 if (perms != myacl->permset) 496 return (0); 497 498 switch (richace->e_type) { 499 case RICHACE_ACCESS_ALLOWED_ACE_TYPE: 500 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) 501 return (0); 502 break; 503 case RICHACE_ACCESS_DENIED_ACE_TYPE: 504 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) 505 return (0); 506 break; 507 default: 508 return (0); 509 } 510 511 if (richace->e_flags & RICHACE_SPECIAL_WHO) { 512 switch (richace->e_id) { 513 case RICHACE_OWNER_SPECIAL_ID: 514 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) 515 return (0); 516 break; 517 case RICHACE_GROUP_SPECIAL_ID: 518 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) 519 return (0); 520 break; 521 case RICHACE_EVERYONE_SPECIAL_ID: 522 if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) 523 return (0); 524 break; 525 default: 526 /* Invalid e_id */ 527 return (0); 528 } 529 } else if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) { 530 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 531 return (0); 532 if ((gid_t)myacl->qual != richace->e_id) 533 return (0); 534 } else { 535 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 536 return (0); 537 if ((uid_t)myacl->qual != richace->e_id) 538 return (0); 539 } 540 return (1); 541} 542#elif ARCHIVE_ACL_DARWIN 543static int 544acl_match(acl_entry_t aclent, struct myacl_t *myacl) 545{ 546 void *q; 547 uid_t ugid; 548 int r, idtype; 549 acl_tag_t tag_type; 550 acl_permset_t opaque_ps; 551 acl_flagset_t opaque_fs; 552 int perms; 553 554 acl_get_tag_type(aclent, &tag_type); 555 556 /* translate the silly opaque permset to a bitmap */ 557 acl_get_permset(aclent, &opaque_ps); 558 acl_get_flagset_np(aclent, &opaque_fs); 559 perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs); 560 if (perms != myacl->permset) 561 return (0); 562 563 r = 0; 564 switch (tag_type) { 565 case ACL_EXTENDED_ALLOW: 566 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) 567 return (0); 568 break; 569 case ACL_EXTENDED_DENY: 570 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) 571 return (0); 572 break; 573 default: 574 return (0); 575 } 576 q = acl_get_qualifier(aclent); 577 if (q == NULL) 578 return (0); 579 r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype); 580 acl_free(q); 581 if (r != 0) 582 return (0); 583 switch (idtype) { 584 case ID_TYPE_UID: 585 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 586 return (0); 587 if ((uid_t)myacl->qual != ugid) 588 return (0); 589 break; 590 case ID_TYPE_GID: 591 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 592 return (0); 593 if ((gid_t)myacl->qual != ugid) 594 return (0); 595 break; 596 default: 597 return (0); 598 } 599 return (1); 600} 601#else /* ARCHIVE_ACL_FREEBSD_NFS4 */ 602static int 603acl_match(acl_entry_t aclent, struct myacl_t *myacl) 604{ 605 gid_t g, *gp; 606 uid_t u, *up; 607 acl_entry_type_t entry_type; 608 acl_tag_t tag_type; 609 acl_permset_t opaque_ps; 610 acl_flagset_t opaque_fs; 611 int perms; 612 613 acl_get_tag_type(aclent, &tag_type); 614 acl_get_entry_type_np(aclent, &entry_type); 615 616 /* translate the silly opaque permset to a bitmap */ 617 acl_get_permset(aclent, &opaque_ps); 618 acl_get_flagset_np(aclent, &opaque_fs); 619 perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs); 620 if (perms != myacl->permset) 621 return (0); 622 623 switch (entry_type) { 624 case ACL_ENTRY_TYPE_ALLOW: 625 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) 626 return (0); 627 break; 628 case ACL_ENTRY_TYPE_DENY: 629 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) 630 return (0); 631 break; 632 case ACL_ENTRY_TYPE_AUDIT: 633 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT) 634 return (0); 635 case ACL_ENTRY_TYPE_ALARM: 636 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM) 637 return (0); 638 default: 639 return (0); 640 } 641 642 switch (tag_type) { 643 case ACL_USER_OBJ: 644 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0); 645 break; 646 case ACL_USER: 647 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 648 return (0); 649 up = acl_get_qualifier(aclent); 650 u = *up; 651 acl_free(up); 652 if ((uid_t)myacl->qual != u) 653 return (0); 654 break; 655 case ACL_GROUP_OBJ: 656 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0); 657 break; 658 case ACL_GROUP: 659 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 660 return (0); 661 gp = acl_get_qualifier(aclent); 662 g = *gp; 663 acl_free(gp); 664 if ((gid_t)myacl->qual != g) 665 return (0); 666 break; 667 case ACL_MASK: 668 if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0); 669 break; 670 case ACL_EVERYONE: 671 if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0); 672 break; 673 } 674 return (1); 675} 676#endif /* various ARCHIVE_ACL_NFS4 implementations */ 677 678static void 679compare_acls( 680#if ARCHIVE_ACL_SUNOS_NFS4 681 void *aclp, 682 int aclcnt, 683#elif ARCHIVE_ACL_LIBRICHACL 684 struct richacl *richacl, 685#else 686 acl_t acl, 687#endif 688 struct myacl_t *myacls, const char *filename, int start, int end) 689{ 690 int *marker; 691 int matched; 692 int i, n; 693#if ARCHIVE_ACL_SUNOS_NFS4 694 int e; 695 ace_t *acl_entry; 696#elif ARCHIVE_ACL_LIBRICHACL 697 int e; 698 struct richace *acl_entry; 699 int aclcnt; 700#else 701 int entry_id = ACL_FIRST_ENTRY; 702 acl_entry_t acl_entry; 703#if ARCHIVE_ACL_DARWIN 704 const int acl_get_entry_ret = 0; 705#else 706 const int acl_get_entry_ret = 1; 707#endif 708#endif 709 710#if ARCHIVE_ACL_SUNOS_NFS4 711 if (aclp == NULL) 712 return; 713#elif ARCHIVE_ACL_LIBRICHACL 714 if (richacl == NULL) 715 return; 716 aclcnt = richacl->a_count; 717#else 718 if (acl == NULL) 719 return; 720#endif 721 722 n = end - start; 723 marker = malloc(sizeof(marker[0]) * (n + 1)); 724 for (i = 0; i < n; i++) 725 marker[i] = i + start; 726#if !ARCHIVE_ACL_DARWIN 727 /* Always include the first ACE. */ 728 if (start > 0) { 729 marker[n] = 0; 730 ++n; 731 } 732#endif 733 734 /* 735 * Iterate over acls in system acl object, try to match each 736 * one with an item in the myacls array. 737 */ 738#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL 739 for (e = 0; e < aclcnt; e++) 740#else 741 while (acl_get_entry_ret == acl_get_entry(acl, entry_id, &acl_entry)) 742#endif 743 { 744#if ARCHIVE_ACL_SUNOS_NFS4 745 acl_entry = &((ace_t *)aclp)[e]; 746#elif ARCHIVE_ACL_LIBRICHACL 747 acl_entry = &(richacl->a_entries[e]); 748#else 749 /* After the first time... */ 750 entry_id = ACL_NEXT_ENTRY; 751#endif 752 /* Search for a matching entry (tag and qualifier) */ 753 for (i = 0, matched = 0; i < n && !matched; i++) { 754 if (acl_match(acl_entry, &myacls[marker[i]])) { 755 /* We found a match; remove it. */ 756 marker[i] = marker[n - 1]; 757 n--; 758 matched = 1; 759 } 760 } 761 762 failure("ACL entry on file %s that shouldn't be there", 763 filename); 764 assert(matched == 1); 765 } 766 767 /* Dump entries in the myacls array that weren't in the system acl. */ 768 for (i = 0; i < n; ++i) { 769 failure(" ACL entry %d missing from %s: " 770 "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", 771 marker[i], filename, 772 myacls[marker[i]].type, myacls[marker[i]].permset, 773 myacls[marker[i]].tag, myacls[marker[i]].qual, 774 myacls[marker[i]].name); 775 assert(0); /* Record this as a failure. */ 776 } 777 free(marker); 778} 779 780static void 781compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char *filename, int start, int end) 782{ 783 int *marker; 784 int matched; 785 int i, n; 786 int type, permset, tag, qual; 787 const char *name; 788 789 /* Count ACL entries in myacls array and allocate an indirect array. */ 790 n = end - start; 791 marker = malloc(sizeof(marker[0]) * (n + 1)); 792 for (i = 0; i < n; i++) 793 marker[i] = i + start; 794 /* Always include the first ACE. */ 795 if (start > 0) { 796 marker[n] = 0; 797 ++n; 798 } 799 800 /* 801 * Iterate over acls in entry, try to match each 802 * one with an item in the myacls array. 803 */ 804 assertEqualInt(n, archive_entry_acl_reset(ae, 805 ARCHIVE_ENTRY_ACL_TYPE_NFS4)); 806 while (ARCHIVE_OK == archive_entry_acl_next(ae, 807 ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) { 808 809 /* Search for a matching entry (tag and qualifier) */ 810 for (i = 0, matched = 0; i < n && !matched; i++) { 811 if (tag == myacls[marker[i]].tag 812 && qual == myacls[marker[i]].qual 813 && permset == myacls[marker[i]].permset 814 && type == myacls[marker[i]].type) { 815 /* We found a match; remove it. */ 816 marker[i] = marker[n - 1]; 817 n--; 818 matched = 1; 819 } 820 } 821 822 failure("ACL entry on file that shouldn't be there: " 823 "type=%#010x,permset=%#010x,tag=%d,qual=%d", 824 type,permset,tag,qual); 825 assert(matched == 1); 826 } 827 828 /* Dump entries in the myacls array that weren't in the system acl. */ 829 for (i = 0; i < n; ++i) { 830 failure(" ACL entry %d missing from %s: " 831 "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", 832 marker[i], filename, 833 myacls[marker[i]].type, myacls[marker[i]].permset, 834 myacls[marker[i]].tag, myacls[marker[i]].qual, 835 myacls[marker[i]].name); 836 assert(0); /* Record this as a failure. */ 837 } 838 free(marker); 839} 840#endif /* ARCHIVE_ACL_NFS4 */ 841 842/* 843 * Verify ACL restore-to-disk. This test is Platform-specific. 844 */ 845 846DEFINE_TEST(test_acl_platform_nfs4) 847{ 848#if !ARCHIVE_ACL_NFS4 849 skipping("NFS4 ACLs are not supported on this platform"); 850#else /* ARCHIVE_ACL_NFS4 */ 851 char buff[64]; 852 int i; 853 struct stat st; 854 struct archive *a; 855 struct archive_entry *ae; 856#if ARCHIVE_ACL_DARWIN /* On MacOS we skip trivial ACLs in some tests */ 857 const int regcnt = acls_reg_cnt - 4; 858 const int dircnt = acls_dir_cnt - 4; 859#else 860 const int regcnt = acls_reg_cnt; 861 const int dircnt = acls_dir_cnt; 862#endif 863#if ARCHIVE_ACL_SUNOS_NFS4 864 void *aclp; 865 int aclcnt; 866#elif ARCHIVE_ACL_LIBRICHACL 867 struct richacl *richacl; 868#else /* !ARCHIVE_ACL_SUNOS_NFS4 */ 869 acl_t acl; 870#endif 871 872 assertMakeFile("pretest", 0644, "a"); 873 874 if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) { 875 skipping("NFS4 ACLs are not writable on this filesystem"); 876 return; 877 } 878 879 /* Create a write-to-disk object. */ 880 assert(NULL != (a = archive_write_disk_new())); 881 archive_write_disk_set_options(a, 882 ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL); 883 884 /* Populate an archive entry with some metadata, including ACL info */ 885 ae = archive_entry_new(); 886 assert(ae != NULL); 887 archive_entry_set_pathname(ae, "testall"); 888 archive_entry_set_filetype(ae, AE_IFREG); 889 archive_entry_set_perm(ae, 0654); 890 archive_entry_set_mtime(ae, 123456, 7890); 891 archive_entry_set_size(ae, 0); 892 set_acls(ae, acls_reg, 0, acls_reg_cnt); 893 894 /* Write the entry to disk, including ACLs. */ 895 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 896 897 /* Likewise for a dir. */ 898 archive_entry_set_pathname(ae, "dirall"); 899 archive_entry_set_filetype(ae, AE_IFDIR); 900 archive_entry_set_perm(ae, 0654); 901 archive_entry_set_mtime(ae, 123456, 7890); 902 set_acls(ae, acls_dir, 0, acls_dir_cnt); 903 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 904 905 for (i = 0; i < acls_dir_cnt; ++i) { 906 sprintf(buff, "dir%d", i); 907 archive_entry_set_pathname(ae, buff); 908 archive_entry_set_filetype(ae, AE_IFDIR); 909 archive_entry_set_perm(ae, 0654); 910 archive_entry_set_mtime(ae, 123456 + i, 7891 + i); 911 set_acls(ae, acls_dir, i, i + 1); 912 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 913 } 914 915 archive_entry_free(ae); 916 917 /* Close the archive. */ 918 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 919 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 920 921 /* Verify the data on disk. */ 922 assertEqualInt(0, stat("testall", &st)); 923 assertEqualInt(st.st_mtime, 123456); 924#if ARCHIVE_ACL_SUNOS_NFS4 925 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "testall"); 926 failure("acl(\"%s\"): errno = %d (%s)", "testall", errno, 927 strerror(errno)); 928 assert(aclp != NULL); 929#elif ARCHIVE_ACL_LIBRICHACL 930 richacl = richacl_get_file("testall"); 931 failure("richacl_get_file(\"%s\"): errno = %d (%s)", "testall", errno, 932 strerror(errno)); 933 assert(richacl != NULL); 934#else 935#if ARCHIVE_ACL_DARWIN 936 acl = acl_get_file("testall", ACL_TYPE_EXTENDED); 937#else 938 acl = acl_get_file("testall", ACL_TYPE_NFS4); 939#endif 940 failure("acl_get_file(\"%s\"): errno = %d (%s)", "testall", errno, 941 strerror(errno)); 942 assert(acl != (acl_t)NULL); 943#endif 944#if ARCHIVE_ACL_SUNOS_NFS4 945 compare_acls(aclp, aclcnt, acls_reg, "testall", 0, regcnt); 946 free(aclp); 947 aclp = NULL; 948#elif ARCHIVE_ACL_LIBRICHACL 949 compare_acls(richacl, acls_reg, "testall", 0, regcnt); 950 richacl_free(richacl); 951#else 952 compare_acls(acl, acls_reg, "testall", 0, regcnt); 953 acl_free(acl); 954#endif 955 956 957 /* Verify single-permission dirs on disk. */ 958 for (i = 0; i < dircnt; ++i) { 959 sprintf(buff, "dir%d", i); 960 assertEqualInt(0, stat(buff, &st)); 961 assertEqualInt(st.st_mtime, 123456 + i); 962#if ARCHIVE_ACL_SUNOS_NFS4 963 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, buff); 964 failure("acl(\"%s\"): errno = %d (%s)", buff, errno, 965 strerror(errno)); 966 assert(aclp != NULL); 967#elif ARCHIVE_ACL_LIBRICHACL 968 richacl = richacl_get_file(buff); 969 /* First and last two dir do not return a richacl */ 970 if ((i == 0 || i >= dircnt - 2) && richacl == NULL && 971 errno == ENODATA) 972 continue; 973 failure("richacl_get_file(\"%s\"): errno = %d (%s)", buff, 974 errno, strerror(errno)); 975 assert(richacl != NULL); 976#else 977#if ARCHIVE_ACL_DARWIN 978 acl = acl_get_file(buff, ACL_TYPE_EXTENDED); 979#else 980 acl = acl_get_file(buff, ACL_TYPE_NFS4); 981#endif 982 failure("acl_get_file(\"%s\"): errno = %d (%s)", buff, errno, 983 strerror(errno)); 984 assert(acl != (acl_t)NULL); 985#endif 986#if ARCHIVE_ACL_SUNOS_NFS4 987 compare_acls(aclp, aclcnt, acls_dir, buff, i, i + 1); 988 free(aclp); 989 aclp = NULL; 990#elif ARCHIVE_ACL_LIBRICHACL 991 compare_acls(richacl, acls_dir, buff, i, i + 1); 992 richacl_free(richacl); 993#else 994 compare_acls(acl, acls_dir, buff, i, i + 1); 995 acl_free(acl); 996#endif 997 } 998 999 /* Verify "dirall" on disk. */ 1000 assertEqualInt(0, stat("dirall", &st)); 1001 assertEqualInt(st.st_mtime, 123456); 1002#if ARCHIVE_ACL_SUNOS_NFS4 1003 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "dirall"); 1004 failure("acl(\"%s\"): errno = %d (%s)", "dirall", errno, 1005 strerror(errno)); 1006 assert(aclp != NULL); 1007#elif ARCHIVE_ACL_LIBRICHACL 1008 richacl = richacl_get_file("dirall"); 1009 failure("richacl_get_file(\"%s\"): errno = %d (%s)", "dirall", 1010 errno, strerror(errno)); 1011 assert(richacl != NULL); 1012#else 1013#if ARCHIVE_ACL_DARWIN 1014 acl = acl_get_file("dirall", ACL_TYPE_EXTENDED); 1015#else 1016 acl = acl_get_file("dirall", ACL_TYPE_NFS4); 1017#endif 1018 failure("acl_get_file(\"%s\"): errno = %d (%s)", "dirall", errno, 1019 strerror(errno)); 1020 assert(acl != (acl_t)NULL); 1021#endif 1022#if ARCHIVE_ACL_SUNOS_NFS4 1023 compare_acls(aclp, aclcnt, acls_dir, "dirall", 0, dircnt); 1024 free(aclp); 1025 aclp = NULL; 1026#elif ARCHIVE_ACL_LIBRICHACL 1027 compare_acls(richacl, acls_dir, "dirall", 0, dircnt); 1028 richacl_free(richacl); 1029#else 1030 compare_acls(acl, acls_dir, "dirall", 0, dircnt); 1031 acl_free(acl); 1032#endif 1033 1034 /* Read and compare ACL via archive_read_disk */ 1035 a = archive_read_disk_new(); 1036 assert(a != NULL); 1037 ae = archive_entry_new(); 1038 assert(ae != NULL); 1039 archive_entry_set_pathname(ae, "testall"); 1040 assertEqualInt(ARCHIVE_OK, 1041 archive_read_disk_entry_from_file(a, ae, -1, NULL)); 1042 compare_entry_acls(ae, acls_reg, "testall", 0, acls_reg_cnt); 1043 archive_entry_free(ae); 1044 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1045 1046 /* Read and compare ACL via archive_read_disk */ 1047 a = archive_read_disk_new(); 1048 assert(a != NULL); 1049 ae = archive_entry_new(); 1050 assert(ae != NULL); 1051 archive_entry_set_pathname(ae, "dirall"); 1052 assertEqualInt(ARCHIVE_OK, 1053 archive_read_disk_entry_from_file(a, ae, -1, NULL)); 1054 compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt); 1055 archive_entry_free(ae); 1056 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1057#endif /* ARCHIVE_ACL_NFS4 */ 1058} 1059