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 27 /* 28 * Exercise the system-independent portion of the ACL support. 29 * Check that archive_entry objects can save and restore POSIX.1e-style 30 * ACL data. 31 * 32 * This should work on all systems, regardless of whether local 33 * filesystems support ACLs or not. 34 */ 35 36 static struct archive_test_acl_t acls0[] = { 37 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, 38 ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, 39 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 40 ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, 41 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE, 42 ARCHIVE_ENTRY_ACL_OTHER, 0, "" }, 43 }; 44 45 static struct archive_test_acl_t acls1[] = { 46 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, 47 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 48 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 49 ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, 50 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 51 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 52 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE, 53 ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, 54 }; 55 56 static struct archive_test_acl_t acls2[] = { 57 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ, 58 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 59 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 60 ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, 61 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0, 62 ARCHIVE_ENTRY_ACL_USER, 78, "user78" }, 63 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 64 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 65 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007, 66 ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, 67 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE, 68 ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, 69 }; 70 71 /* 72 * NFS4 entry types; attempts to set these on top of POSIX.1e 73 * attributes should fail. 74 */ 75 static struct archive_test_acl_t acls_nfs4[] = { 76 /* NFS4 types */ 77 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ, 78 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 79 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_READ, 80 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 81 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, ARCHIVE_ENTRY_ACL_READ, 82 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 83 { ARCHIVE_ENTRY_ACL_TYPE_ALARM, ARCHIVE_ENTRY_ACL_READ, 84 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 85 86 /* NFS4 tags */ 87 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 88 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, 89 90 /* NFS4 inheritance markers */ 91 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 92 ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 93 ARCHIVE_ENTRY_ACL_USER, 79, "" }, 94 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 95 ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 96 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 97 }; 98 99 DEFINE_TEST(test_acl_posix1e) 100 { 101 struct archive_entry *ae; 102 int i; 103 104 /* Create a simple archive_entry. */ 105 assert((ae = archive_entry_new()) != NULL); 106 archive_entry_set_pathname(ae, "file"); 107 archive_entry_set_mode(ae, S_IFREG | 0777); 108 109 /* Basic owner/owning group should just update mode bits. */ 110 111 /* 112 * Note: This features of libarchive's ACL implementation 113 * shouldn't be relied on and should probably be removed. It 114 * was done to identify trivial ACLs so we could avoid 115 * triggering unnecessary extensions. It's better to identify 116 * trivial ACLs at the point they are being read from disk. 117 */ 118 assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); 119 failure("Basic ACLs shouldn't be stored as extended ACLs"); 120 assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 121 failure("Basic ACLs should set mode to 0142, not %04o", 122 archive_entry_mode(ae)&0777); 123 assert((archive_entry_mode(ae) & 0777) == 0142); 124 125 /* With any extended ACL entry, we should read back a full set. */ 126 assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); 127 failure("One extended ACL should flag all ACLs to be returned."); 128 129 /* Check that entry contains only POSIX.1e types */ 130 assert((archive_entry_acl_types(ae) & 131 ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0); 132 assert((archive_entry_acl_types(ae) & 133 ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0); 134 135 assert(4 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 136 assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), 137 ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142); 138 failure("Basic ACLs should set mode to 0142, not %04o", 139 archive_entry_mode(ae)&0777); 140 assert((archive_entry_mode(ae) & 0777) == 0142); 141 142 143 /* A more extensive set of ACLs. */ 144 assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); 145 assertEqualInt(6, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 146 assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), 147 ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543); 148 failure("Basic ACLs should set mode to 0543, not %04o", 149 archive_entry_mode(ae)&0777); 150 assert((archive_entry_mode(ae) & 0777) == 0543); 151 152 /* 153 * Check that clearing ACLs gets rid of them all by repeating 154 * the first test. 155 */ 156 assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); 157 failure("Basic ACLs shouldn't be stored as extended ACLs"); 158 assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 159 failure("Basic ACLs should set mode to 0142, not %04o", 160 archive_entry_mode(ae)&0777); 161 assert((archive_entry_mode(ae) & 0777) == 0142); 162 163 /* 164 * Different types of malformed ACL entries that should 165 * fail when added to existing POSIX.1e ACLs. 166 */ 167 assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); 168 for (i = 0; i < (int)(sizeof(acls_nfs4)/sizeof(acls_nfs4[0])); ++i) { 169 struct archive_test_acl_t *p = &acls_nfs4[i]; 170 failure("Malformed ACL test #%d", i); 171 assertEqualInt(ARCHIVE_FAILED, 172 archive_entry_acl_add_entry(ae, 173 p->type, p->permset, p->tag, p->qual, p->name)); 174 assertEqualInt(6, 175 archive_entry_acl_reset(ae, 176 ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); 177 } 178 archive_entry_free(ae); 179 } 180