1198160Srrs/*- 2198160Srrs * Copyright (c) 2008, 2009 Edward Tomasz Napiera��a <trasz@FreeBSD.org> 3198160Srrs * 4198160Srrs * Redistribution and use in source and binary forms, with or without 5198160Srrs * modification, are permitted provided that the following conditions 6198160Srrs * are met: 7198160Srrs * 1. Redistributions of source code must retain the above copyright 8198160Srrs * notice, this list of conditions and the following disclaimer. 9198160Srrs * 2. Redistributions in binary form must reproduce the above copyright 10198160Srrs * notice, this list of conditions and the following disclaimer in the 11198160Srrs * documentation and/or other materials provided with the distribution. 12198160Srrs * 13198160Srrs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14198160Srrs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15198160Srrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16198160Srrs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17198160Srrs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18198160Srrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19198160Srrs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20198160Srrs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21198160Srrs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22198160Srrs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23198160Srrs * SUCH DAMAGE. 24198160Srrs */ 25198160Srrs 26198160Srrs#include <sys/param.h> 27198160Srrs#include <sys/systm.h> 28198160Srrs#include <sys/types.h> 29211994Sjchandra#include <sys/malloc.h> 30211994Sjchandra#include <sys/errno.h> 31211994Sjchandra#include <sys/zfs_acl.h> 32198160Srrs#include <sys/acl.h> 33198160Srrs 34198160Srrsstruct zfs2bsd { 35198160Srrs uint32_t zb_zfs; 36198956Srrs int zb_bsd; 37198160Srrs}; 38198160Srrs 39198160Srrsstruct zfs2bsd perms[] = {{ACE_READ_DATA, ACL_READ_DATA}, 40198160Srrs {ACE_WRITE_DATA, ACL_WRITE_DATA}, 41198160Srrs {ACE_EXECUTE, ACL_EXECUTE}, 42198160Srrs {ACE_APPEND_DATA, ACL_APPEND_DATA}, 43198160Srrs {ACE_DELETE_CHILD, ACL_DELETE_CHILD}, 44198160Srrs {ACE_DELETE, ACL_DELETE}, 45198160Srrs {ACE_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, 46198160Srrs {ACE_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, 47198160Srrs {ACE_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, 48198160Srrs {ACE_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, 49198160Srrs {ACE_READ_ACL, ACL_READ_ACL}, 50198160Srrs {ACE_WRITE_ACL, ACL_WRITE_ACL}, 51198160Srrs {ACE_WRITE_OWNER, ACL_WRITE_OWNER}, 52198160Srrs {ACE_SYNCHRONIZE, ACL_SYNCHRONIZE}, 53198160Srrs {0, 0}}; 54198160Srrs 55198160Srrsstruct zfs2bsd flags[] = {{ACE_FILE_INHERIT_ACE, 56198160Srrs ACL_ENTRY_FILE_INHERIT}, 57198160Srrs {ACE_DIRECTORY_INHERIT_ACE, 58198160Srrs ACL_ENTRY_DIRECTORY_INHERIT}, 59198160Srrs {ACE_NO_PROPAGATE_INHERIT_ACE, 60198160Srrs ACL_ENTRY_NO_PROPAGATE_INHERIT}, 61198160Srrs {ACE_INHERIT_ONLY_ACE, 62198160Srrs ACL_ENTRY_INHERIT_ONLY}, 63198160Srrs {ACE_INHERITED_ACE, 64198160Srrs ACL_ENTRY_INHERITED}, 65198160Srrs {ACE_SUCCESSFUL_ACCESS_ACE_FLAG, 66198160Srrs ACL_ENTRY_SUCCESSFUL_ACCESS}, 67198160Srrs {ACE_FAILED_ACCESS_ACE_FLAG, 68198160Srrs ACL_ENTRY_FAILED_ACCESS}, 69198160Srrs {0, 0}}; 70198956Srrs 71198160Srrsstatic int 72198956Srrs_bsd_from_zfs(uint32_t zfs, const struct zfs2bsd *table) 73198956Srrs{ 74198160Srrs const struct zfs2bsd *tmp; 75198160Srrs int bsd = 0; 76198160Srrs 77198160Srrs for (tmp = table; tmp->zb_zfs != 0; tmp++) { 78198160Srrs if (zfs & tmp->zb_zfs) 79198160Srrs bsd |= tmp->zb_bsd; 80198160Srrs } 81198160Srrs 82198160Srrs return (bsd); 83198160Srrs} 84198160Srrs 85198160Srrsstatic uint32_t 86198160Srrs_zfs_from_bsd(int bsd, const struct zfs2bsd *table) 87198160Srrs{ 88198160Srrs const struct zfs2bsd *tmp; 89198160Srrs uint32_t zfs = 0; 90198160Srrs 91198160Srrs for (tmp = table; tmp->zb_bsd != 0; tmp++) { 92198160Srrs if (bsd & tmp->zb_bsd) 93198160Srrs zfs |= tmp->zb_zfs; 94198160Srrs } 95198160Srrs 96198160Srrs return (zfs); 97198160Srrs} 98198160Srrs 99198160Srrsint 100198625Srrsacl_from_aces(struct acl *aclp, const ace_t *aces, int nentries) 101198160Srrs{ 102198160Srrs int i; 103198160Srrs struct acl_entry *entry; 104198160Srrs const ace_t *ace; 105198160Srrs 106198160Srrs if (nentries < 1) { 107198160Srrs printf("acl_from_aces: empty ZFS ACL; returning EINVAL.\n"); 108198160Srrs return (EINVAL); 109198160Srrs } 110198160Srrs 111198160Srrs if (nentries > ACL_MAX_ENTRIES) { 112198160Srrs /* 113198160Srrs * I believe it may happen only when moving a pool 114198160Srrs * from SunOS to FreeBSD. 115198625Srrs */ 116 printf("acl_from_aces: ZFS ACL too big to fit " 117 "into 'struct acl'; returning EINVAL.\n"); 118 return (EINVAL); 119 } 120 121 bzero(aclp, sizeof(*aclp)); 122 aclp->acl_maxcnt = ACL_MAX_ENTRIES; 123 aclp->acl_cnt = nentries; 124 125 for (i = 0; i < nentries; i++) { 126 entry = &(aclp->acl_entry[i]); 127 ace = &(aces[i]); 128 129 if (ace->a_flags & ACE_OWNER) 130 entry->ae_tag = ACL_USER_OBJ; 131 else if (ace->a_flags & ACE_GROUP) 132 entry->ae_tag = ACL_GROUP_OBJ; 133 else if (ace->a_flags & ACE_EVERYONE) 134 entry->ae_tag = ACL_EVERYONE; 135 else if (ace->a_flags & ACE_IDENTIFIER_GROUP) 136 entry->ae_tag = ACL_GROUP; 137 else 138 entry->ae_tag = ACL_USER; 139 140 if (entry->ae_tag == ACL_USER || entry->ae_tag == ACL_GROUP) 141 entry->ae_id = ace->a_who; 142 else 143 entry->ae_id = ACL_UNDEFINED_ID; 144 145 entry->ae_perm = _bsd_from_zfs(ace->a_access_mask, perms); 146 entry->ae_flags = _bsd_from_zfs(ace->a_flags, flags); 147 148 switch (ace->a_type) { 149 case ACE_ACCESS_ALLOWED_ACE_TYPE: 150 entry->ae_entry_type = ACL_ENTRY_TYPE_ALLOW; 151 break; 152 case ACE_ACCESS_DENIED_ACE_TYPE: 153 entry->ae_entry_type = ACL_ENTRY_TYPE_DENY; 154 break; 155 case ACE_SYSTEM_AUDIT_ACE_TYPE: 156 entry->ae_entry_type = ACL_ENTRY_TYPE_AUDIT; 157 break; 158 case ACE_SYSTEM_ALARM_ACE_TYPE: 159 entry->ae_entry_type = ACL_ENTRY_TYPE_ALARM; 160 break; 161 default: 162 panic("acl_from_aces: a_type is 0x%x", ace->a_type); 163 } 164 } 165 166 return (0); 167} 168 169void 170aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp) 171{ 172 int i; 173 const struct acl_entry *entry; 174 ace_t *ace; 175 176 bzero(aces, sizeof(*aces) * aclp->acl_cnt); 177 178 *nentries = aclp->acl_cnt; 179 180 for (i = 0; i < aclp->acl_cnt; i++) { 181 entry = &(aclp->acl_entry[i]); 182 ace = &(aces[i]); 183 184 ace->a_who = entry->ae_id; 185 186 if (entry->ae_tag == ACL_USER_OBJ) 187 ace->a_flags = ACE_OWNER; 188 else if (entry->ae_tag == ACL_GROUP_OBJ) 189 ace->a_flags = (ACE_GROUP | ACE_IDENTIFIER_GROUP); 190 else if (entry->ae_tag == ACL_GROUP) 191 ace->a_flags = ACE_IDENTIFIER_GROUP; 192 else if (entry->ae_tag == ACL_EVERYONE) 193 ace->a_flags = ACE_EVERYONE; 194 else /* ACL_USER */ 195 ace->a_flags = 0; 196 197 ace->a_access_mask = _zfs_from_bsd(entry->ae_perm, perms); 198 ace->a_flags |= _zfs_from_bsd(entry->ae_flags, flags); 199 200 switch (entry->ae_entry_type) { 201 case ACL_ENTRY_TYPE_ALLOW: 202 ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; 203 break; 204 case ACL_ENTRY_TYPE_DENY: 205 ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE; 206 break; 207 case ACL_ENTRY_TYPE_ALARM: 208 ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE; 209 break; 210 case ACL_ENTRY_TYPE_AUDIT: 211 ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE; 212 break; 213 default: 214 panic("aces_from_acl: ae_entry_type is 0x%x", entry->ae_entry_type); 215 } 216 } 217} 218