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/types.h> 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/types.h> 34 #include <sys/malloc.h> 35 #include <sys/errno.h> 36 #include <sys/zfs_acl.h> 37 #include <sys/acl.h> 38 39 struct zfs2bsd { 40 uint32_t zb_zfs; 41 int zb_bsd; 42 }; 43 44 struct zfs2bsd perms[] = {{ACE_READ_DATA, ACL_READ_DATA}, 45 {ACE_WRITE_DATA, ACL_WRITE_DATA}, 46 {ACE_EXECUTE, ACL_EXECUTE}, 47 {ACE_APPEND_DATA, ACL_APPEND_DATA}, 48 {ACE_DELETE_CHILD, ACL_DELETE_CHILD}, 49 {ACE_DELETE, ACL_DELETE}, 50 {ACE_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, 51 {ACE_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, 52 {ACE_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, 53 {ACE_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, 54 {ACE_READ_ACL, ACL_READ_ACL}, 55 {ACE_WRITE_ACL, ACL_WRITE_ACL}, 56 {ACE_WRITE_OWNER, ACL_WRITE_OWNER}, 57 {ACE_SYNCHRONIZE, ACL_SYNCHRONIZE}, 58 {0, 0}}; 59 60 struct zfs2bsd flags[] = {{ACE_FILE_INHERIT_ACE, 61 ACL_ENTRY_FILE_INHERIT}, 62 {ACE_DIRECTORY_INHERIT_ACE, 63 ACL_ENTRY_DIRECTORY_INHERIT}, 64 {ACE_NO_PROPAGATE_INHERIT_ACE, 65 ACL_ENTRY_NO_PROPAGATE_INHERIT}, 66 {ACE_INHERIT_ONLY_ACE, 67 ACL_ENTRY_INHERIT_ONLY}, 68 {ACE_INHERITED_ACE, 69 ACL_ENTRY_INHERITED}, 70 {ACE_SUCCESSFUL_ACCESS_ACE_FLAG, 71 ACL_ENTRY_SUCCESSFUL_ACCESS}, 72 {ACE_FAILED_ACCESS_ACE_FLAG, 73 ACL_ENTRY_FAILED_ACCESS}, 74 {0, 0}}; 75 76 static int 77 _bsd_from_zfs(uint32_t zfs, const struct zfs2bsd *table) 78 { 79 const struct zfs2bsd *tmp; 80 int bsd = 0; 81 82 for (tmp = table; tmp->zb_zfs != 0; tmp++) { 83 if (zfs & tmp->zb_zfs) 84 bsd |= tmp->zb_bsd; 85 } 86 87 return (bsd); 88 } 89 90 static uint32_t 91 _zfs_from_bsd(int bsd, const struct zfs2bsd *table) 92 { 93 const struct zfs2bsd *tmp; 94 uint32_t zfs = 0; 95 96 for (tmp = table; tmp->zb_bsd != 0; tmp++) { 97 if (bsd & tmp->zb_bsd) 98 zfs |= tmp->zb_zfs; 99 } 100 101 return (zfs); 102 } 103 104 int 105 acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries) 106 { 107 int i; 108 struct acl_entry *entry; 109 const ace_t *ace; 110 111 if (nentries < 1) { 112 printf("acl_from_aces: empty ZFS ACL; returning EINVAL.\n"); 113 return (EINVAL); 114 } 115 116 if (nentries > ACL_MAX_ENTRIES) { 117 /* 118 * I believe it may happen only when moving a pool 119 * from SunOS to FreeBSD. 120 */ 121 printf("acl_from_aces: ZFS ACL too big to fit " 122 "into 'struct acl'; returning EINVAL.\n"); 123 return (EINVAL); 124 } 125 126 bzero(aclp, sizeof (*aclp)); 127 aclp->acl_maxcnt = ACL_MAX_ENTRIES; 128 aclp->acl_cnt = nentries; 129 130 for (i = 0; i < nentries; i++) { 131 entry = &(aclp->acl_entry[i]); 132 ace = &(aces[i]); 133 134 if (ace->a_flags & ACE_OWNER) 135 entry->ae_tag = ACL_USER_OBJ; 136 else if (ace->a_flags & ACE_GROUP) 137 entry->ae_tag = ACL_GROUP_OBJ; 138 else if (ace->a_flags & ACE_EVERYONE) 139 entry->ae_tag = ACL_EVERYONE; 140 else if (ace->a_flags & ACE_IDENTIFIER_GROUP) 141 entry->ae_tag = ACL_GROUP; 142 else 143 entry->ae_tag = ACL_USER; 144 145 if (entry->ae_tag == ACL_USER || entry->ae_tag == ACL_GROUP) 146 entry->ae_id = ace->a_who; 147 else 148 entry->ae_id = ACL_UNDEFINED_ID; 149 150 entry->ae_perm = _bsd_from_zfs(ace->a_access_mask, perms); 151 entry->ae_flags = _bsd_from_zfs(ace->a_flags, flags); 152 153 switch (ace->a_type) { 154 case ACE_ACCESS_ALLOWED_ACE_TYPE: 155 entry->ae_entry_type = ACL_ENTRY_TYPE_ALLOW; 156 break; 157 case ACE_ACCESS_DENIED_ACE_TYPE: 158 entry->ae_entry_type = ACL_ENTRY_TYPE_DENY; 159 break; 160 case ACE_SYSTEM_AUDIT_ACE_TYPE: 161 entry->ae_entry_type = ACL_ENTRY_TYPE_AUDIT; 162 break; 163 case ACE_SYSTEM_ALARM_ACE_TYPE: 164 entry->ae_entry_type = ACL_ENTRY_TYPE_ALARM; 165 break; 166 default: 167 panic("acl_from_aces: a_type is 0x%x", ace->a_type); 168 } 169 } 170 171 return (0); 172 } 173 174 void 175 aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp) 176 { 177 int i; 178 const struct acl_entry *entry; 179 ace_t *ace; 180 181 bzero(aces, sizeof (*aces) * aclp->acl_cnt); 182 183 *nentries = aclp->acl_cnt; 184 185 for (i = 0; i < aclp->acl_cnt; i++) { 186 entry = &(aclp->acl_entry[i]); 187 ace = &(aces[i]); 188 189 ace->a_who = entry->ae_id; 190 191 if (entry->ae_tag == ACL_USER_OBJ) 192 ace->a_flags = ACE_OWNER; 193 else if (entry->ae_tag == ACL_GROUP_OBJ) 194 ace->a_flags = (ACE_GROUP | ACE_IDENTIFIER_GROUP); 195 else if (entry->ae_tag == ACL_GROUP) 196 ace->a_flags = ACE_IDENTIFIER_GROUP; 197 else if (entry->ae_tag == ACL_EVERYONE) 198 ace->a_flags = ACE_EVERYONE; 199 else /* ACL_USER */ 200 ace->a_flags = 0; 201 202 ace->a_access_mask = _zfs_from_bsd(entry->ae_perm, perms); 203 ace->a_flags |= _zfs_from_bsd(entry->ae_flags, flags); 204 205 switch (entry->ae_entry_type) { 206 case ACL_ENTRY_TYPE_ALLOW: 207 ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; 208 break; 209 case ACL_ENTRY_TYPE_DENY: 210 ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE; 211 break; 212 case ACL_ENTRY_TYPE_ALARM: 213 ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE; 214 break; 215 case ACL_ENTRY_TYPE_AUDIT: 216 ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE; 217 break; 218 default: 219 panic("aces_from_acl: ae_entry_type is 0x%x", 220 entry->ae_entry_type); 221 } 222 } 223 } 224