1 /*- 2 * Copyright (c) 2008, 2009 Edward Tomasz Napierała <trasz@FreeBSD.org> 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 AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/types.h> 33 #include <sys/malloc.h> 34 #include <sys/errno.h> 35 #include <sys/zfs_acl.h> 36 #include <sys/acl.h> 37 38 struct zfs2bsd { 39 uint32_t zb_zfs; 40 int zb_bsd; 41 }; 42 43 struct zfs2bsd perms[] = {{ACE_READ_DATA, ACL_READ_DATA}, 44 {ACE_WRITE_DATA, ACL_WRITE_DATA}, 45 {ACE_EXECUTE, ACL_EXECUTE}, 46 {ACE_APPEND_DATA, ACL_APPEND_DATA}, 47 {ACE_DELETE_CHILD, ACL_DELETE_CHILD}, 48 {ACE_DELETE, ACL_DELETE}, 49 {ACE_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, 50 {ACE_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, 51 {ACE_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, 52 {ACE_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, 53 {ACE_READ_ACL, ACL_READ_ACL}, 54 {ACE_WRITE_ACL, ACL_WRITE_ACL}, 55 {ACE_WRITE_OWNER, ACL_WRITE_OWNER}, 56 {ACE_SYNCHRONIZE, ACL_SYNCHRONIZE}, 57 {0, 0}}; 58 59 struct zfs2bsd flags[] = {{ACE_FILE_INHERIT_ACE, 60 ACL_ENTRY_FILE_INHERIT}, 61 {ACE_DIRECTORY_INHERIT_ACE, 62 ACL_ENTRY_DIRECTORY_INHERIT}, 63 {ACE_NO_PROPAGATE_INHERIT_ACE, 64 ACL_ENTRY_NO_PROPAGATE_INHERIT}, 65 {ACE_INHERIT_ONLY_ACE, 66 ACL_ENTRY_INHERIT_ONLY}, 67 {ACE_SUCCESSFUL_ACCESS_ACE_FLAG, 68 ACL_ENTRY_SUCCESSFUL_ACCESS}, 69 {ACE_FAILED_ACCESS_ACE_FLAG, 70 ACL_ENTRY_FAILED_ACCESS}, 71 {0, 0}}; 72 73 static int 74 _bsd_from_zfs(uint32_t zfs, const struct zfs2bsd *table) 75 { 76 const struct zfs2bsd *tmp; 77 int bsd = 0; 78 79 for (tmp = table; tmp->zb_zfs != 0; tmp++) { 80 if (zfs & tmp->zb_zfs) 81 bsd |= tmp->zb_bsd; 82 } 83 84 return (bsd); 85 } 86 87 static uint32_t 88 _zfs_from_bsd(int bsd, const struct zfs2bsd *table) 89 { 90 const struct zfs2bsd *tmp; 91 uint32_t zfs = 0; 92 93 for (tmp = table; tmp->zb_bsd != 0; tmp++) { 94 if (bsd & tmp->zb_bsd) 95 zfs |= tmp->zb_zfs; 96 } 97 98 return (zfs); 99 } 100 101 int 102 acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries) 103 { 104 int i; 105 struct acl_entry *entry; 106 const ace_t *ace; 107 108 if (nentries < 1) { 109 printf("acl_from_aces: empty ZFS ACL; returning EINVAL.\n"); 110 return (EINVAL); 111 } 112 113 if (nentries > ACL_MAX_ENTRIES) { 114 /* 115 * I believe it may happen only when moving a pool 116 * from SunOS to FreeBSD. 117 */ 118 printf("acl_from_aces: ZFS ACL too big to fit " 119 "into 'struct acl'; returning EINVAL.\n"); 120 return (EINVAL); 121 } 122 123 bzero(aclp, sizeof(*aclp)); 124 aclp->acl_maxcnt = ACL_MAX_ENTRIES; 125 aclp->acl_cnt = nentries; 126 127 for (i = 0; i < nentries; i++) { 128 entry = &(aclp->acl_entry[i]); 129 ace = &(aces[i]); 130 131 if (ace->a_flags & ACE_OWNER) 132 entry->ae_tag = ACL_USER_OBJ; 133 else if (ace->a_flags & ACE_GROUP) 134 entry->ae_tag = ACL_GROUP_OBJ; 135 else if (ace->a_flags & ACE_EVERYONE) 136 entry->ae_tag = ACL_EVERYONE; 137 else if (ace->a_flags & ACE_IDENTIFIER_GROUP) 138 entry->ae_tag = ACL_GROUP; 139 else 140 entry->ae_tag = ACL_USER; 141 142 if (entry->ae_tag == ACL_USER || entry->ae_tag == ACL_GROUP) 143 entry->ae_id = ace->a_who; 144 else 145 entry->ae_id = ACL_UNDEFINED_ID; 146 147 entry->ae_perm = _bsd_from_zfs(ace->a_access_mask, perms); 148 entry->ae_flags = _bsd_from_zfs(ace->a_flags, flags); 149 150 switch (ace->a_type) { 151 case ACE_ACCESS_ALLOWED_ACE_TYPE: 152 entry->ae_entry_type = ACL_ENTRY_TYPE_ALLOW; 153 break; 154 case ACE_ACCESS_DENIED_ACE_TYPE: 155 entry->ae_entry_type = ACL_ENTRY_TYPE_DENY; 156 break; 157 case ACE_SYSTEM_AUDIT_ACE_TYPE: 158 entry->ae_entry_type = ACL_ENTRY_TYPE_AUDIT; 159 break; 160 case ACE_SYSTEM_ALARM_ACE_TYPE: 161 entry->ae_entry_type = ACL_ENTRY_TYPE_ALARM; 162 break; 163 default: 164 panic("acl_from_aces: a_type is 0x%x", ace->a_type); 165 } 166 } 167 168 return (0); 169 } 170 171 void 172 aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp) 173 { 174 int i; 175 const struct acl_entry *entry; 176 ace_t *ace; 177 178 bzero(aces, sizeof(*aces) * aclp->acl_cnt); 179 180 *nentries = aclp->acl_cnt; 181 182 for (i = 0; i < aclp->acl_cnt; i++) { 183 entry = &(aclp->acl_entry[i]); 184 ace = &(aces[i]); 185 186 ace->a_who = entry->ae_id; 187 188 if (entry->ae_tag == ACL_USER_OBJ) 189 ace->a_flags = ACE_OWNER; 190 else if (entry->ae_tag == ACL_GROUP_OBJ) 191 ace->a_flags = (ACE_GROUP | ACE_IDENTIFIER_GROUP); 192 else if (entry->ae_tag == ACL_GROUP) 193 ace->a_flags = ACE_IDENTIFIER_GROUP; 194 else if (entry->ae_tag == ACL_EVERYONE) 195 ace->a_flags = ACE_EVERYONE; 196 else /* ACL_USER */ 197 ace->a_flags = 0; 198 199 ace->a_access_mask = _zfs_from_bsd(entry->ae_perm, perms); 200 ace->a_flags |= _zfs_from_bsd(entry->ae_flags, flags); 201 202 switch (entry->ae_entry_type) { 203 case ACL_ENTRY_TYPE_ALLOW: 204 ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; 205 break; 206 case ACL_ENTRY_TYPE_DENY: 207 ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE; 208 break; 209 case ACL_ENTRY_TYPE_ALARM: 210 ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE; 211 break; 212 case ACL_ENTRY_TYPE_AUDIT: 213 ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE; 214 break; 215 default: 216 panic("aces_from_acl: ae_entry_type is 0x%x", entry->ae_entry_type); 217 } 218 } 219 } 220