test_acl_platform_nfs4.c revision 328828
1/*- 2 * Copyright (c) 2003-2010 Tim Kientzle 3 * Copyright (c) 2017 Martin Matuska 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 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. 14 * 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. 25 */ 26#include "test.h" 27__FBSDID("$FreeBSD$"); 28 29#if ARCHIVE_ACL_NFS4 30#if HAVE_SYS_ACL_H 31#define _ACL_PRIVATE 32#include <sys/acl.h> 33#endif 34#if HAVE_SYS_RICHACL_H 35#include <sys/richacl.h> 36#endif 37#if HAVE_MEMBERSHIP_H 38#include <membership.h> 39#endif 40 41struct myacl_t { 42 int type; 43 int permset; 44 int tag; 45 int qual; /* GID or UID of user/group, depending on tag. */ 46 const char *name; /* Name of user/group, depending on tag. */ 47}; 48 49static struct myacl_t acls_reg[] = { 50#if !ARCHIVE_ACL_DARWIN 51 /* For this test, we need the file owner to be able to read and write the ACL. */ 52 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 53 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, 54 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""}, 55#endif 56 /* An entry for each type. */ 57 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 58 ARCHIVE_ENTRY_ACL_USER, 108, "user108" }, 59 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, 60 ARCHIVE_ENTRY_ACL_USER, 109, "user109" }, 61 62 /* An entry for each permission. */ 63 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 64 ARCHIVE_ENTRY_ACL_USER, 112, "user112" }, 65 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA, 66 ARCHIVE_ENTRY_ACL_USER, 113, "user113" }, 67 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA, 68 ARCHIVE_ENTRY_ACL_USER, 115, "user115" }, 69 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA, 70 ARCHIVE_ENTRY_ACL_USER, 117, "user117" }, 71 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 72 ARCHIVE_ENTRY_ACL_USER, 119, "user119" }, 73 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 74 ARCHIVE_ENTRY_ACL_USER, 120, "user120" }, 75 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 76 ARCHIVE_ENTRY_ACL_USER, 122, "user122" }, 77 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 78 ARCHIVE_ENTRY_ACL_USER, 123, "user123" }, 79 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE, 80 ARCHIVE_ENTRY_ACL_USER, 124, "user124" }, 81 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, 82 ARCHIVE_ENTRY_ACL_USER, 125, "user125" }, 83 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL, 84 ARCHIVE_ENTRY_ACL_USER, 126, "user126" }, 85 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER, 86 ARCHIVE_ENTRY_ACL_USER, 127, "user127" }, 87 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 88 ARCHIVE_ENTRY_ACL_USER, 128, "user128" }, 89 90 /* One entry for each qualifier. */ 91 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 92 ARCHIVE_ENTRY_ACL_USER, 135, "user135" }, 93// { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 94// ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 95 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 96 ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" }, 97#if !ARCHIVE_ACL_DARWIN 98 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 99 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 100 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 101 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } 102#else /* MacOS - mode 0654 */ 103 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, 104 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 105 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 106 ARCHIVE_ENTRY_ACL_READ_DATA | 107 ARCHIVE_ENTRY_ACL_WRITE_DATA | 108 ARCHIVE_ENTRY_ACL_APPEND_DATA | 109 ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 110 ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | 111 ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 112 ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | 113 ARCHIVE_ENTRY_ACL_READ_ACL | 114 ARCHIVE_ENTRY_ACL_WRITE_ACL | 115 ARCHIVE_ENTRY_ACL_WRITE_OWNER | 116 ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 117 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 118 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 119 ARCHIVE_ENTRY_ACL_READ_DATA | 120 ARCHIVE_ENTRY_ACL_EXECUTE | 121 ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 122 ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 123 ARCHIVE_ENTRY_ACL_READ_ACL | 124 ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 125 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 126 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 127 ARCHIVE_ENTRY_ACL_READ_DATA | 128 ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 129 ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 130 ARCHIVE_ENTRY_ACL_READ_ACL | 131 ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 132 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } 133#endif 134}; 135 136static const int acls_reg_cnt = (int)(sizeof(acls_reg)/sizeof(acls_reg[0])); 137 138static struct myacl_t acls_dir[] = { 139 /* For this test, we need to be able to read and write the ACL. */ 140#if !ARCHIVE_ACL_DARWIN 141 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL, 142 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""}, 143#endif 144 145 /* An entry for each type. */ 146 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 147 ARCHIVE_ENTRY_ACL_USER, 101, "user101" }, 148 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 149 ARCHIVE_ENTRY_ACL_USER, 102, "user102" }, 150 151 /* An entry for each permission. */ 152 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 153 ARCHIVE_ENTRY_ACL_USER, 201, "user201" }, 154 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE, 155 ARCHIVE_ENTRY_ACL_USER, 202, "user202" }, 156 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, 157 ARCHIVE_ENTRY_ACL_USER, 203, "user203" }, 158 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 159 ARCHIVE_ENTRY_ACL_USER, 204, "user204" }, 160 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 161 ARCHIVE_ENTRY_ACL_USER, 205, "user205" }, 162 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD, 163 ARCHIVE_ENTRY_ACL_USER, 206, "user206" }, 164 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 165 ARCHIVE_ENTRY_ACL_USER, 207, "user207" }, 166 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 167 ARCHIVE_ENTRY_ACL_USER, 208, "user208" }, 168 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE, 169 ARCHIVE_ENTRY_ACL_USER, 209, "user209" }, 170 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, 171 ARCHIVE_ENTRY_ACL_USER, 210, "user210" }, 172 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL, 173 ARCHIVE_ENTRY_ACL_USER, 211, "user211" }, 174 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER, 175 ARCHIVE_ENTRY_ACL_USER, 212, "user212" }, 176 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 177 ARCHIVE_ENTRY_ACL_USER, 213, "user213" }, 178 179 /* One entry with each inheritance value. */ 180 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 181 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 182 ARCHIVE_ENTRY_ACL_USER, 301, "user301" }, 183 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 184 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, 185 ARCHIVE_ENTRY_ACL_USER, 302, "user302" }, 186 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 187 ARCHIVE_ENTRY_ACL_READ_DATA | 188 ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT | 189 ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, 190 ARCHIVE_ENTRY_ACL_USER, 303, "user303" }, 191 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 192 ARCHIVE_ENTRY_ACL_READ_DATA | 193 ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT | 194 ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, 195 ARCHIVE_ENTRY_ACL_USER, 304, "user304" }, 196#if !defined(ARCHIVE_ACL_SUNOS_NFS4) || defined(ACE_INHERITED_ACE) 197 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 198 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, 199 ARCHIVE_ENTRY_ACL_USER, 305, "user305" }, 200#endif 201 202#if 0 203 /* FreeBSD does not support audit entries. */ 204 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 205 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, 206 ARCHIVE_ENTRY_ACL_USER, 401, "user401" }, 207 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 208 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, 209 ARCHIVE_ENTRY_ACL_USER, 402, "user402" }, 210#endif 211 212 /* One entry for each qualifier. */ 213 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 214 ARCHIVE_ENTRY_ACL_USER, 501, "user501" }, 215 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 216 ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" }, 217#if !ARCHIVE_ACL_DARWIN 218 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 219 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 220 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 221 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } 222#else /* MacOS - mode 0654 */ 223 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, 224 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 225 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 226 ARCHIVE_ENTRY_ACL_READ_DATA | 227 ARCHIVE_ENTRY_ACL_WRITE_DATA | 228 ARCHIVE_ENTRY_ACL_APPEND_DATA | 229 ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 230 ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | 231 ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 232 ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | 233 ARCHIVE_ENTRY_ACL_READ_ACL | 234 ARCHIVE_ENTRY_ACL_WRITE_ACL | 235 ARCHIVE_ENTRY_ACL_WRITE_OWNER | 236 ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 237 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 238 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 239 ARCHIVE_ENTRY_ACL_READ_DATA | 240 ARCHIVE_ENTRY_ACL_EXECUTE | 241 ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 242 ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 243 ARCHIVE_ENTRY_ACL_READ_ACL | 244 ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 245 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 246 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 247 ARCHIVE_ENTRY_ACL_READ_DATA | 248 ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | 249 ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 250 ARCHIVE_ENTRY_ACL_READ_ACL | 251 ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 252 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } 253#endif 254}; 255 256static const int acls_dir_cnt = (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); 257 258static void 259set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end) 260{ 261 int i; 262 263 archive_entry_acl_clear(ae); 264#if !ARCHIVE_ACL_DARWIN 265 if (start > 0) { 266 assertEqualInt(ARCHIVE_OK, 267 archive_entry_acl_add_entry(ae, 268 acls[0].type, acls[0].permset, acls[0].tag, 269 acls[0].qual, acls[0].name)); 270 } 271#endif 272 for (i = start; i < end; i++) { 273 assertEqualInt(ARCHIVE_OK, 274 archive_entry_acl_add_entry(ae, 275 acls[i].type, acls[i].permset, acls[i].tag, 276 acls[i].qual, acls[i].name)); 277 } 278} 279 280static int 281#if ARCHIVE_ACL_SUNOS_NFS4 282acl_permset_to_bitmap(uint32_t mask) 283#elif ARCHIVE_ACL_LIBRICHACL 284acl_permset_to_bitmap(unsigned int mask) 285#else 286acl_permset_to_bitmap(acl_permset_t opaque_ps) 287#endif 288{ 289 static struct { int portable; int machine; } perms[] = { 290#ifdef ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL permissions */ 291 {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE}, 292 {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA}, 293 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY}, 294 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA}, 295 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE}, 296 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA}, 297 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY}, 298 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS}, 299 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS}, 300 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD}, 301 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES}, 302 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES}, 303 {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE}, 304 {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL}, 305 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL}, 306 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER}, 307 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE} 308#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL permissions */ 309 {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, 310 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, 311 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, 312 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, 313 {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, 314 {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, 315 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, 316 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, 317 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, 318 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, 319 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, 320 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES}, 321 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES}, 322 {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY}, 323 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY}, 324 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER}, 325#if HAVE_DECL_ACL_SYNCHRONIZE 326 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} 327#endif 328#elif ARCHIVE_ACL_LIBRICHACL 329 {ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE}, 330 {ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA}, 331 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY}, 332 {ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA}, 333 {ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE}, 334 {ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA}, 335 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY}, 336 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS}, 337 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS}, 338 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD}, 339 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES}, 340 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES}, 341 {ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE}, 342 {ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL}, 343 {ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL}, 344 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER}, 345 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE} 346#else /* FreeBSD NFSv4 ACL permissions */ 347 {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, 348 {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, 349 {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, 350 {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, 351 {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, 352 {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, 353 {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, 354 {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, 355 {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, 356 {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, 357 {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, 358 {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, 359 {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, 360 {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL}, 361 {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL}, 362 {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER}, 363 {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} 364#endif 365 }; 366 int i, permset = 0; 367 368 for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i) 369#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL 370 if (mask & perms[i].machine) 371#else 372 if (acl_get_perm_np(opaque_ps, perms[i].machine)) 373#endif 374 permset |= perms[i].portable; 375 return permset; 376} 377 378static int 379#if ARCHIVE_ACL_SUNOS_NFS4 380acl_flagset_to_bitmap(uint16_t flags) 381#elif ARCHIVE_ACL_LIBRICHACL 382acl_flagset_to_bitmap(int flags) 383#else 384acl_flagset_to_bitmap(acl_flagset_t opaque_fs) 385#endif 386{ 387 static struct { int portable; int machine; } perms[] = { 388#if ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL inheritance flags */ 389 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE}, 390 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE}, 391 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE}, 392 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE}, 393 {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, 394 {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG}, 395#ifdef ACE_INHERITED_ACE 396 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE} 397#endif 398#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL inheritance flags */ 399 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, 400 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, 401 {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#ifdef ACL_ENTRY_INHERITED 412 {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, 413#endif 414 {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, 415 {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, 416 {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, 417 {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS}, 418 {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS}, 419 {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY} 420#endif 421 }; 422 int i, flagset = 0; 423 424 for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i) 425#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL 426 if (flags & perms[i].machine) 427#else 428 if (acl_get_flag_np(opaque_fs, perms[i].machine)) 429#endif 430 flagset |= perms[i].portable; 431 return flagset; 432} 433 434#if ARCHIVE_ACL_SUNOS_NFS4 435static int 436acl_match(ace_t *ace, struct myacl_t *myacl) 437{ 438 int perms; 439 440 perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags); 441 442 if (perms != myacl->permset) 443 return (0); 444 445 switch (ace->a_type) { 446 case ACE_ACCESS_ALLOWED_ACE_TYPE: 447 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) 448 return (0); 449 break; 450 case ACE_ACCESS_DENIED_ACE_TYPE: 451 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) 452 return (0); 453 break; 454 case ACE_SYSTEM_AUDIT_ACE_TYPE: 455 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT) 456 return (0); 457 break; 458 case ACE_SYSTEM_ALARM_ACE_TYPE: 459 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM) 460 return (0); 461 break; 462 default: 463 return (0); 464 } 465 466 if (ace->a_flags & ACE_OWNER) { 467 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) 468 return (0); 469 } else if (ace->a_flags & ACE_GROUP) { 470 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) 471 return (0); 472 } else if (ace->a_flags & ACE_EVERYONE) { 473 if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) 474 return (0); 475 } else if (ace->a_flags & ACE_IDENTIFIER_GROUP) { 476 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 477 return (0); 478 if ((gid_t)myacl->qual != ace->a_who) 479 return (0); 480 } else { 481 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 482 return (0); 483 if ((uid_t)myacl->qual != ace->a_who) 484 return (0); 485 } 486 return (1); 487} 488#elif ARCHIVE_ACL_LIBRICHACL 489static int 490acl_match(struct richace *richace, struct myacl_t *myacl) 491{ 492 int perms; 493 494 perms = acl_permset_to_bitmap(richace->e_mask) | 495 acl_flagset_to_bitmap(richace->e_flags); 496 497 if (perms != myacl->permset) 498 return (0); 499 500 switch (richace->e_type) { 501 case RICHACE_ACCESS_ALLOWED_ACE_TYPE: 502 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) 503 return (0); 504 break; 505 case RICHACE_ACCESS_DENIED_ACE_TYPE: 506 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) 507 return (0); 508 break; 509 default: 510 return (0); 511 } 512 513 if (richace->e_flags & RICHACE_SPECIAL_WHO) { 514 switch (richace->e_id) { 515 case RICHACE_OWNER_SPECIAL_ID: 516 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) 517 return (0); 518 break; 519 case RICHACE_GROUP_SPECIAL_ID: 520 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) 521 return (0); 522 break; 523 case RICHACE_EVERYONE_SPECIAL_ID: 524 if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) 525 return (0); 526 break; 527 default: 528 /* Invalid e_id */ 529 return (0); 530 } 531 } else if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) { 532 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 533 return (0); 534 if ((gid_t)myacl->qual != richace->e_id) 535 return (0); 536 } else { 537 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 538 return (0); 539 if ((uid_t)myacl->qual != richace->e_id) 540 return (0); 541 } 542 return (1); 543} 544#elif ARCHIVE_ACL_DARWIN 545static int 546acl_match(acl_entry_t aclent, struct myacl_t *myacl) 547{ 548 void *q; 549 uid_t ugid; 550 int r, idtype; 551 acl_tag_t tag_type; 552 acl_permset_t opaque_ps; 553 acl_flagset_t opaque_fs; 554 int perms; 555 556 acl_get_tag_type(aclent, &tag_type); 557 558 /* translate the silly opaque permset to a bitmap */ 559 acl_get_permset(aclent, &opaque_ps); 560 acl_get_flagset_np(aclent, &opaque_fs); 561 perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs); 562 if (perms != myacl->permset) 563 return (0); 564 565 r = 0; 566 switch (tag_type) { 567 case ACL_EXTENDED_ALLOW: 568 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) 569 return (0); 570 break; 571 case ACL_EXTENDED_DENY: 572 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) 573 return (0); 574 break; 575 default: 576 return (0); 577 } 578 q = acl_get_qualifier(aclent); 579 if (q == NULL) 580 return (0); 581 r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype); 582 acl_free(q); 583 if (r != 0) 584 return (0); 585 switch (idtype) { 586 case ID_TYPE_UID: 587 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 588 return (0); 589 if ((uid_t)myacl->qual != ugid) 590 return (0); 591 break; 592 case ID_TYPE_GID: 593 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 594 return (0); 595 if ((gid_t)myacl->qual != ugid) 596 return (0); 597 break; 598 default: 599 return (0); 600 } 601 return (1); 602} 603#else /* ARCHIVE_ACL_FREEBSD_NFS4 */ 604static int 605acl_match(acl_entry_t aclent, struct myacl_t *myacl) 606{ 607 gid_t g, *gp; 608 uid_t u, *up; 609 acl_entry_type_t entry_type; 610 acl_tag_t tag_type; 611 acl_permset_t opaque_ps; 612 acl_flagset_t opaque_fs; 613 int perms; 614 615 acl_get_tag_type(aclent, &tag_type); 616 acl_get_entry_type_np(aclent, &entry_type); 617 618 /* translate the silly opaque permset to a bitmap */ 619 acl_get_permset(aclent, &opaque_ps); 620 acl_get_flagset_np(aclent, &opaque_fs); 621 perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs); 622 if (perms != myacl->permset) 623 return (0); 624 625 switch (entry_type) { 626 case ACL_ENTRY_TYPE_ALLOW: 627 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) 628 return (0); 629 break; 630 case ACL_ENTRY_TYPE_DENY: 631 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) 632 return (0); 633 break; 634 case ACL_ENTRY_TYPE_AUDIT: 635 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT) 636 return (0); 637 case ACL_ENTRY_TYPE_ALARM: 638 if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM) 639 return (0); 640 default: 641 return (0); 642 } 643 644 switch (tag_type) { 645 case ACL_USER_OBJ: 646 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0); 647 break; 648 case ACL_USER: 649 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 650 return (0); 651 up = acl_get_qualifier(aclent); 652 u = *up; 653 acl_free(up); 654 if ((uid_t)myacl->qual != u) 655 return (0); 656 break; 657 case ACL_GROUP_OBJ: 658 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0); 659 break; 660 case ACL_GROUP: 661 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 662 return (0); 663 gp = acl_get_qualifier(aclent); 664 g = *gp; 665 acl_free(gp); 666 if ((gid_t)myacl->qual != g) 667 return (0); 668 break; 669 case ACL_MASK: 670 if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0); 671 break; 672 case ACL_EVERYONE: 673 if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0); 674 break; 675 } 676 return (1); 677} 678#endif /* various ARCHIVE_ACL_NFS4 implementations */ 679 680static void 681compare_acls( 682#if ARCHIVE_ACL_SUNOS_NFS4 683 void *aclp, 684 int aclcnt, 685#elif ARCHIVE_ACL_LIBRICHACL 686 struct richacl *richacl, 687#else 688 acl_t acl, 689#endif 690 struct myacl_t *myacls, const char *filename, int start, int end) 691{ 692 int *marker; 693 int matched; 694 int i, n; 695#if ARCHIVE_ACL_SUNOS_NFS4 696 int e; 697 ace_t *acl_entry; 698#elif ARCHIVE_ACL_LIBRICHACL 699 int e; 700 struct richace *acl_entry; 701 int aclcnt; 702#else 703 int entry_id = ACL_FIRST_ENTRY; 704 acl_entry_t acl_entry; 705#if ARCHIVE_ACL_DARWIN 706 const int acl_get_entry_ret = 0; 707#else 708 const int acl_get_entry_ret = 1; 709#endif 710#endif 711 712#if ARCHIVE_ACL_SUNOS_NFS4 713 if (aclp == NULL) 714 return; 715#elif ARCHIVE_ACL_LIBRICHACL 716 if (richacl == NULL) 717 return; 718 aclcnt = richacl->a_count; 719#else 720 if (acl == NULL) 721 return; 722#endif 723 724 n = end - start; 725 marker = malloc(sizeof(marker[0]) * (n + 1)); 726 for (i = 0; i < n; i++) 727 marker[i] = i + start; 728#if !ARCHIVE_ACL_DARWIN 729 /* Always include the first ACE. */ 730 if (start > 0) { 731 marker[n] = 0; 732 ++n; 733 } 734#endif 735 736 /* 737 * Iterate over acls in system acl object, try to match each 738 * one with an item in the myacls array. 739 */ 740#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL 741 for (e = 0; e < aclcnt; e++) 742#else 743 while (acl_get_entry_ret == acl_get_entry(acl, entry_id, &acl_entry)) 744#endif 745 { 746#if ARCHIVE_ACL_SUNOS_NFS4 747 acl_entry = &((ace_t *)aclp)[e]; 748#elif ARCHIVE_ACL_LIBRICHACL 749 acl_entry = &(richacl->a_entries[e]); 750#else 751 /* After the first time... */ 752 entry_id = ACL_NEXT_ENTRY; 753#endif 754 /* Search for a matching entry (tag and qualifier) */ 755 for (i = 0, matched = 0; i < n && !matched; i++) { 756 if (acl_match(acl_entry, &myacls[marker[i]])) { 757 /* We found a match; remove it. */ 758 marker[i] = marker[n - 1]; 759 n--; 760 matched = 1; 761 } 762 } 763 764 failure("ACL entry on file %s that shouldn't be there", 765 filename); 766 assert(matched == 1); 767 } 768 769 /* Dump entries in the myacls array that weren't in the system acl. */ 770 for (i = 0; i < n; ++i) { 771 failure(" ACL entry %d missing from %s: " 772 "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", 773 marker[i], filename, 774 myacls[marker[i]].type, myacls[marker[i]].permset, 775 myacls[marker[i]].tag, myacls[marker[i]].qual, 776 myacls[marker[i]].name); 777 assert(0); /* Record this as a failure. */ 778 } 779 free(marker); 780} 781 782static void 783compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char *filename, int start, int end) 784{ 785 int *marker; 786 int matched; 787 int i, n; 788 int type, permset, tag, qual; 789 const char *name; 790 791 /* Count ACL entries in myacls array and allocate an indirect array. */ 792 n = end - start; 793 marker = malloc(sizeof(marker[0]) * (n + 1)); 794 for (i = 0; i < n; i++) 795 marker[i] = i + start; 796 /* Always include the first ACE. */ 797 if (start > 0) { 798 marker[n] = 0; 799 ++n; 800 } 801 802 /* 803 * Iterate over acls in entry, try to match each 804 * one with an item in the myacls array. 805 */ 806 assertEqualInt(n, archive_entry_acl_reset(ae, 807 ARCHIVE_ENTRY_ACL_TYPE_NFS4)); 808 while (ARCHIVE_OK == archive_entry_acl_next(ae, 809 ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) { 810 811 /* Search for a matching entry (tag and qualifier) */ 812 for (i = 0, matched = 0; i < n && !matched; i++) { 813 if (tag == myacls[marker[i]].tag 814 && qual == myacls[marker[i]].qual 815 && permset == myacls[marker[i]].permset 816 && type == myacls[marker[i]].type) { 817 /* We found a match; remove it. */ 818 marker[i] = marker[n - 1]; 819 n--; 820 matched = 1; 821 } 822 } 823 824 failure("ACL entry on file that shouldn't be there: " 825 "type=%#010x,permset=%#010x,tag=%d,qual=%d", 826 type,permset,tag,qual); 827 assert(matched == 1); 828 } 829 830 /* Dump entries in the myacls array that weren't in the system acl. */ 831 for (i = 0; i < n; ++i) { 832 failure(" ACL entry %d missing from %s: " 833 "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", 834 marker[i], filename, 835 myacls[marker[i]].type, myacls[marker[i]].permset, 836 myacls[marker[i]].tag, myacls[marker[i]].qual, 837 myacls[marker[i]].name); 838 assert(0); /* Record this as a failure. */ 839 } 840 free(marker); 841} 842#endif /* ARCHIVE_ACL_NFS4 */ 843 844/* 845 * Verify ACL restore-to-disk. This test is Platform-specific. 846 */ 847 848DEFINE_TEST(test_acl_platform_nfs4) 849{ 850#if !ARCHIVE_ACL_NFS4 851 skipping("NFS4 ACLs are not supported on this platform"); 852#else /* ARCHIVE_ACL_NFS4 */ 853 char buff[64]; 854 int i; 855 struct stat st; 856 struct archive *a; 857 struct archive_entry *ae; 858#if ARCHIVE_ACL_DARWIN /* On MacOS we skip trivial ACLs in some tests */ 859 const int regcnt = acls_reg_cnt - 4; 860 const int dircnt = acls_dir_cnt - 4; 861#else 862 const int regcnt = acls_reg_cnt; 863 const int dircnt = acls_dir_cnt; 864#endif 865#if ARCHIVE_ACL_SUNOS_NFS4 866 void *aclp; 867 int aclcnt; 868#elif ARCHIVE_ACL_LIBRICHACL 869 struct richacl *richacl; 870#else /* !ARCHIVE_ACL_SUNOS_NFS4 */ 871 acl_t acl; 872#endif 873 874 assertMakeFile("pretest", 0644, "a"); 875 876 if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) { 877 skipping("NFS4 ACLs are not writable on this filesystem"); 878 return; 879 } 880 881 /* Create a write-to-disk object. */ 882 assert(NULL != (a = archive_write_disk_new())); 883 archive_write_disk_set_options(a, 884 ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL); 885 886 /* Populate an archive entry with some metadata, including ACL info */ 887 ae = archive_entry_new(); 888 assert(ae != NULL); 889 archive_entry_set_pathname(ae, "testall"); 890 archive_entry_set_filetype(ae, AE_IFREG); 891 archive_entry_set_perm(ae, 0654); 892 archive_entry_set_mtime(ae, 123456, 7890); 893 archive_entry_set_size(ae, 0); 894 set_acls(ae, acls_reg, 0, acls_reg_cnt); 895 896 /* Write the entry to disk, including ACLs. */ 897 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 898 899 /* Likewise for a dir. */ 900 archive_entry_set_pathname(ae, "dirall"); 901 archive_entry_set_filetype(ae, AE_IFDIR); 902 archive_entry_set_perm(ae, 0654); 903 archive_entry_set_mtime(ae, 123456, 7890); 904 set_acls(ae, acls_dir, 0, acls_dir_cnt); 905 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 906 907 for (i = 0; i < acls_dir_cnt; ++i) { 908 sprintf(buff, "dir%d", i); 909 archive_entry_set_pathname(ae, buff); 910 archive_entry_set_filetype(ae, AE_IFDIR); 911 archive_entry_set_perm(ae, 0654); 912 archive_entry_set_mtime(ae, 123456 + i, 7891 + i); 913 set_acls(ae, acls_dir, i, i + 1); 914 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 915 } 916 917 archive_entry_free(ae); 918 919 /* Close the archive. */ 920 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 921 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 922 923 /* Verify the data on disk. */ 924 assertEqualInt(0, stat("testall", &st)); 925 assertEqualInt(st.st_mtime, 123456); 926#if ARCHIVE_ACL_SUNOS_NFS4 927 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "testall"); 928 failure("acl(\"%s\"): errno = %d (%s)", "testall", errno, 929 strerror(errno)); 930 assert(aclp != NULL); 931#elif ARCHIVE_ACL_LIBRICHACL 932 richacl = richacl_get_file("testall"); 933 failure("richacl_get_file(\"%s\"): errno = %d (%s)", "testall", errno, 934 strerror(errno)); 935 assert(richacl != NULL); 936#else 937#if ARCHIVE_ACL_DARWIN 938 acl = acl_get_file("testall", ACL_TYPE_EXTENDED); 939#else 940 acl = acl_get_file("testall", ACL_TYPE_NFS4); 941#endif 942 failure("acl_get_file(\"%s\"): errno = %d (%s)", "testall", errno, 943 strerror(errno)); 944 assert(acl != (acl_t)NULL); 945#endif 946#if ARCHIVE_ACL_SUNOS_NFS4 947 compare_acls(aclp, aclcnt, acls_reg, "testall", 0, regcnt); 948 free(aclp); 949 aclp = NULL; 950#elif ARCHIVE_ACL_LIBRICHACL 951 compare_acls(richacl, acls_reg, "testall", 0, regcnt); 952 richacl_free(richacl); 953#else 954 compare_acls(acl, acls_reg, "testall", 0, regcnt); 955 acl_free(acl); 956#endif 957 958 959 /* Verify single-permission dirs on disk. */ 960 for (i = 0; i < dircnt; ++i) { 961 sprintf(buff, "dir%d", i); 962 assertEqualInt(0, stat(buff, &st)); 963 assertEqualInt(st.st_mtime, 123456 + i); 964#if ARCHIVE_ACL_SUNOS_NFS4 965 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, buff); 966 failure("acl(\"%s\"): errno = %d (%s)", buff, errno, 967 strerror(errno)); 968 assert(aclp != NULL); 969#elif ARCHIVE_ACL_LIBRICHACL 970 richacl = richacl_get_file(buff); 971 /* First and last two dir do not return a richacl */ 972 if ((i == 0 || i >= dircnt - 2) && richacl == NULL && 973 errno == ENODATA) 974 continue; 975 failure("richacl_get_file(\"%s\"): errno = %d (%s)", buff, 976 errno, strerror(errno)); 977 assert(richacl != NULL); 978#else 979#if ARCHIVE_ACL_DARWIN 980 acl = acl_get_file(buff, ACL_TYPE_EXTENDED); 981#else 982 acl = acl_get_file(buff, ACL_TYPE_NFS4); 983#endif 984 failure("acl_get_file(\"%s\"): errno = %d (%s)", buff, errno, 985 strerror(errno)); 986 assert(acl != (acl_t)NULL); 987#endif 988#if ARCHIVE_ACL_SUNOS_NFS4 989 compare_acls(aclp, aclcnt, acls_dir, buff, i, i + 1); 990 free(aclp); 991 aclp = NULL; 992#elif ARCHIVE_ACL_LIBRICHACL 993 compare_acls(richacl, acls_dir, buff, i, i + 1); 994 richacl_free(richacl); 995#else 996 compare_acls(acl, acls_dir, buff, i, i + 1); 997 acl_free(acl); 998#endif 999 } 1000 1001 /* Verify "dirall" on disk. */ 1002 assertEqualInt(0, stat("dirall", &st)); 1003 assertEqualInt(st.st_mtime, 123456); 1004#if ARCHIVE_ACL_SUNOS_NFS4 1005 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "dirall"); 1006 failure("acl(\"%s\"): errno = %d (%s)", "dirall", errno, 1007 strerror(errno)); 1008 assert(aclp != NULL); 1009#elif ARCHIVE_ACL_LIBRICHACL 1010 richacl = richacl_get_file("dirall"); 1011 failure("richacl_get_file(\"%s\"): errno = %d (%s)", "dirall", 1012 errno, strerror(errno)); 1013 assert(richacl != NULL); 1014#else 1015#if ARCHIVE_ACL_DARWIN 1016 acl = acl_get_file("dirall", ACL_TYPE_EXTENDED); 1017#else 1018 acl = acl_get_file("dirall", ACL_TYPE_NFS4); 1019#endif 1020 failure("acl_get_file(\"%s\"): errno = %d (%s)", "dirall", errno, 1021 strerror(errno)); 1022 assert(acl != (acl_t)NULL); 1023#endif 1024#if ARCHIVE_ACL_SUNOS_NFS4 1025 compare_acls(aclp, aclcnt, acls_dir, "dirall", 0, dircnt); 1026 free(aclp); 1027 aclp = NULL; 1028#elif ARCHIVE_ACL_LIBRICHACL 1029 compare_acls(richacl, acls_dir, "dirall", 0, dircnt); 1030 richacl_free(richacl); 1031#else 1032 compare_acls(acl, acls_dir, "dirall", 0, dircnt); 1033 acl_free(acl); 1034#endif 1035 1036 /* Read and compare ACL via archive_read_disk */ 1037 a = archive_read_disk_new(); 1038 assert(a != NULL); 1039 ae = archive_entry_new(); 1040 assert(ae != NULL); 1041 archive_entry_set_pathname(ae, "testall"); 1042 assertEqualInt(ARCHIVE_OK, 1043 archive_read_disk_entry_from_file(a, ae, -1, NULL)); 1044 compare_entry_acls(ae, acls_reg, "testall", 0, acls_reg_cnt); 1045 archive_entry_free(ae); 1046 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1047 1048 /* Read and compare ACL via archive_read_disk */ 1049 a = archive_read_disk_new(); 1050 assert(a != NULL); 1051 ae = archive_entry_new(); 1052 assert(ae != NULL); 1053 archive_entry_set_pathname(ae, "dirall"); 1054 assertEqualInt(ARCHIVE_OK, 1055 archive_read_disk_entry_from_file(a, ae, -1, NULL)); 1056 compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt); 1057 archive_entry_free(ae); 1058 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 1059#endif /* ARCHIVE_ACL_NFS4 */ 1060} 1061