1 /*- 2 * Copyright (c) 2003-2010 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$"); 27 28 /* 29 * Exercise the system-independent portion of the ACL support. 30 * Check that archive_entry objects can save and restore NFS4 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 acls1[] = { 37 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 38 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 39 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_READ_DATA, 40 ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, 41 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA, 42 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 43 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_WRITE_DATA, 44 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, 45 }; 46 47 static struct archive_test_acl_t acls2[] = { 48 /* An entry for each type. */ 49 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0, 50 ARCHIVE_ENTRY_ACL_USER, 108, "user108" }, 51 { ARCHIVE_ENTRY_ACL_TYPE_DENY, 0, 52 ARCHIVE_ENTRY_ACL_USER, 109, "user109" }, 53 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 0, 54 ARCHIVE_ENTRY_ACL_USER, 110, "user110" }, 55 { ARCHIVE_ENTRY_ACL_TYPE_ALARM, 0, 56 ARCHIVE_ENTRY_ACL_USER, 111, "user111" }, 57 58 /* An entry for each permission. */ 59 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 60 ARCHIVE_ENTRY_ACL_USER, 112, "user112" }, 61 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA, 62 ARCHIVE_ENTRY_ACL_USER, 113, "user113" }, 63 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 64 ARCHIVE_ENTRY_ACL_USER, 114, "user114" }, 65 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA, 66 ARCHIVE_ENTRY_ACL_USER, 115, "user115" }, 67 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE, 68 ARCHIVE_ENTRY_ACL_USER, 116, "user116" }, 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_ADD_SUBDIRECTORY, 72 ARCHIVE_ENTRY_ACL_USER, 118, "user118" }, 73 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 74 ARCHIVE_ENTRY_ACL_USER, 119, "user119" }, 75 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 76 ARCHIVE_ENTRY_ACL_USER, 120, "user120" }, 77 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD, 78 ARCHIVE_ENTRY_ACL_USER, 121, "user121" }, 79 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 80 ARCHIVE_ENTRY_ACL_USER, 122, "user122" }, 81 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 82 ARCHIVE_ENTRY_ACL_USER, 123, "user123" }, 83 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE, 84 ARCHIVE_ENTRY_ACL_USER, 124, "user124" }, 85 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, 86 ARCHIVE_ENTRY_ACL_USER, 125, "user125" }, 87 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL, 88 ARCHIVE_ENTRY_ACL_USER, 126, "user126" }, 89 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER, 90 ARCHIVE_ENTRY_ACL_USER, 127, "user127" }, 91 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 92 ARCHIVE_ENTRY_ACL_USER, 128, "user128" }, 93 94 /* One entry with each inheritance value. */ 95 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 96 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 97 ARCHIVE_ENTRY_ACL_USER, 129, "user129" }, 98 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 99 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, 100 ARCHIVE_ENTRY_ACL_USER, 130, "user130" }, 101 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 102 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, 103 ARCHIVE_ENTRY_ACL_USER, 131, "user131" }, 104 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 105 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, 106 ARCHIVE_ENTRY_ACL_USER, 132, "user132" }, 107 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 108 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, 109 ARCHIVE_ENTRY_ACL_USER, 133, "user133" }, 110 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 111 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, 112 ARCHIVE_ENTRY_ACL_USER, 134, "user134" }, 113 114 /* One entry for each qualifier. */ 115 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 116 ARCHIVE_ENTRY_ACL_USER, 135, "user135" }, 117 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 118 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 119 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 120 ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" }, 121 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 122 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 123 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 124 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, 125 }; 126 127 /* 128 * Entries that should be rejected when we attempt to set them 129 * on an ACL that already has NFS4 entries. 130 */ 131 static struct archive_test_acl_t acls_bad[] = { 132 /* POSIX.1e ACL types */ 133 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, 134 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 135 { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE, 136 ARCHIVE_ENTRY_ACL_USER, 78, "" }, 137 138 /* POSIX.1e tags */ 139 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 140 ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, 141 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, 142 ARCHIVE_ENTRY_ACL_MASK, -1, "" }, 143 144 /* POSIX.1e permissions */ 145 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ, 146 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, 147 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE, 148 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, 149 }; 150 151 DEFINE_TEST(test_acl_nfs4) 152 { 153 struct archive_entry *ae; 154 int i; 155 156 /* Create a simple archive_entry. */ 157 assert((ae = archive_entry_new()) != NULL); 158 archive_entry_set_pathname(ae, "file"); 159 archive_entry_set_mode(ae, S_IFREG | 0777); 160 161 /* Store and read back some basic ACL entries. */ 162 assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); 163 164 /* Check that entry contains only NFSv4 types */ 165 assert((archive_entry_acl_types(ae) & 166 ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0); 167 assert((archive_entry_acl_types(ae) & 168 ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0); 169 170 assertEqualInt(4, 171 archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4)); 172 assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), 173 ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); 174 175 /* A more extensive set of ACLs. */ 176 assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); 177 assertEqualInt(32, 178 archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4)); 179 assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), 180 ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); 181 182 /* 183 * Check that clearing ACLs gets rid of them all by repeating 184 * the first test. 185 */ 186 assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); 187 failure("Basic ACLs shouldn't be stored as extended ACLs"); 188 assertEqualInt(4, 189 archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4)); 190 191 /* 192 * Different types of malformed ACL entries that should 193 * fail when added to existing NFS4 ACLs. 194 */ 195 assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); 196 for (i = 0; i < (int)(sizeof(acls_bad)/sizeof(acls_bad[0])); ++i) { 197 struct archive_test_acl_t *p = &acls_bad[i]; 198 failure("Malformed ACL test #%d", i); 199 assertEqualInt(ARCHIVE_FAILED, 200 archive_entry_acl_add_entry(ae, 201 p->type, p->permset, p->tag, p->qual, p->name)); 202 failure("Malformed ACL test #%d", i); 203 assertEqualInt(32, 204 archive_entry_acl_reset(ae, 205 ARCHIVE_ENTRY_ACL_TYPE_NFS4)); 206 } 207 archive_entry_free(ae); 208 } 209