1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 #include "test.h" 26 __FBSDID("$FreeBSD: src/lib/libarchive/test/test_acl_basic.c,v 1.6 2008/10/19 00:13:57 kientzle Exp $"); 27 28 /* 29 * Exercise the system-independent portion of the ACL support. 30 * Check that archive_entry objects can save and restore POSIX.1e-style 31 * ACL data. 32 * 33 * This should work on all systems, regardless of whether local 34 * filesystems support ACLs or not. 35 */ 36 37 static struct archive_test_acl_t acls0[] = { 38 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, 39 ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, 40 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 41 ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, 42 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE, 43 ARCHIVE_ENTRY_ACL_OTHER, 0, "" }, 44 }; 45 46 static struct archive_test_acl_t acls1[] = { 47 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, 48 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 49 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 50 ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, 51 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 52 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 53 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE, 54 ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, 55 }; 56 57 static struct archive_test_acl_t acls2[] = { 58 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ, 59 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 60 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 61 ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, 62 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0, 63 ARCHIVE_ENTRY_ACL_USER, 78, "user78" }, 64 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 65 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 66 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007, 67 ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, 68 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE, 69 ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, 70 }; 71 72 /* 73 * NFS4 entry types; attempts to set these on top of POSIX.1e 74 * attributes should fail. 75 */ 76 static struct archive_test_acl_t acls_nfs4[] = { 77 /* NFS4 types */ 78 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ, 79 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 80 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_READ, 81 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 82 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, ARCHIVE_ENTRY_ACL_READ, 83 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 84 { ARCHIVE_ENTRY_ACL_TYPE_ALARM, ARCHIVE_ENTRY_ACL_READ, 85 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 86 87 /* NFS4 tags */ 88 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 89 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, 90 91 /* NFS4 inheritance markers */ 92 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 93 ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 94 ARCHIVE_ENTRY_ACL_USER, 79, "" }, 95 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 96 ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 97 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 98 }; 99 100 DEFINE_TEST(test_acl_posix1e) 101 { 102 struct archive_entry *ae; 103 int i; 104 105 /* Create a simple archive_entry. */ 106 assert((ae = archive_entry_new()) != NULL); 107 archive_entry_set_pathname(ae, "file"); 108 archive_entry_set_mode(ae, S_IFREG | 0777); 109 110 /* Basic owner/owning group should just update mode bits. */ 111 112 /* 113 * Note: This features of libarchive's ACL implementation 114 * shouldn't be relied on and should probably be removed. It 115 * was done to identify trivial ACLs so we could avoid 116 * triggering unnecessary extensions. It's better to identify 117 * trivial ACLs at the point they are being read from disk. 118 */ 119 assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); 120 failure("Basic ACLs shouldn't be stored as extended ACLs"); 121 assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 122 failure("Basic ACLs should set mode to 0142, not %04o", 123 archive_entry_mode(ae)&0777); 124 assert((archive_entry_mode(ae) & 0777) == 0142); 125 126 /* With any extended ACL entry, we should read back a full set. */ 127 assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); 128 failure("One extended ACL should flag all ACLs to be returned."); 129 130 /* Check that entry contains only POSIX.1e types */ 131 assert((archive_entry_acl_types(ae) & 132 ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0); 133 assert((archive_entry_acl_types(ae) & 134 ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0); 135 136 assert(4 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 137 assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), 138 ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142); 139 failure("Basic ACLs should set mode to 0142, not %04o", 140 archive_entry_mode(ae)&0777); 141 assert((archive_entry_mode(ae) & 0777) == 0142); 142 143 144 /* A more extensive set of ACLs. */ 145 assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); 146 assertEqualInt(6, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 147 assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), 148 ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543); 149 failure("Basic ACLs should set mode to 0543, not %04o", 150 archive_entry_mode(ae)&0777); 151 assert((archive_entry_mode(ae) & 0777) == 0543); 152 153 /* 154 * Check that clearing ACLs gets rid of them all by repeating 155 * the first test. 156 */ 157 assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); 158 failure("Basic ACLs shouldn't be stored as extended ACLs"); 159 assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 160 failure("Basic ACLs should set mode to 0142, not %04o", 161 archive_entry_mode(ae)&0777); 162 assert((archive_entry_mode(ae) & 0777) == 0142); 163 164 /* 165 * Different types of malformed ACL entries that should 166 * fail when added to existing POSIX.1e ACLs. 167 */ 168 assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); 169 for (i = 0; i < (int)(sizeof(acls_nfs4)/sizeof(acls_nfs4[0])); ++i) { 170 struct archive_test_acl_t *p = &acls_nfs4[i]; 171 failure("Malformed ACL test #%d", i); 172 assertEqualInt(ARCHIVE_FAILED, 173 archive_entry_acl_add_entry(ae, 174 p->type, p->permset, p->tag, p->qual, p->name)); 175 assertEqualInt(6, 176 archive_entry_acl_reset(ae, 177 ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 178 } 179 archive_entry_free(ae); 180 } 181