Path: blob/main/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c
48383 views
/*-1* Copyright (c) 2008, 2009 Edward Tomasz NapieraĆa <[email protected]>2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6* 1. Redistributions of source code must retain the above copyright7* notice, this list of conditions and the following disclaimer.8* 2. Redistributions in binary form must reproduce the above copyright9* notice, this list of conditions and the following disclaimer in the10* documentation and/or other materials provided with the distribution.11*12* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND13* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE14* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE15* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE16* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL17* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS18* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)19* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT20* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY21* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF22* SUCH DAMAGE.23*/2425#include <sys/param.h>26#include <sys/systm.h>27#include <sys/types.h>28#include <sys/malloc.h>29#include <sys/errno.h>30#include <sys/zfs_acl.h>31#include <sys/acl.h>3233struct zfs2bsd {34uint32_t zb_zfs;35int zb_bsd;36};3738struct zfs2bsd perms[] = {{ACE_READ_DATA, ACL_READ_DATA},39{ACE_WRITE_DATA, ACL_WRITE_DATA},40{ACE_EXECUTE, ACL_EXECUTE},41{ACE_APPEND_DATA, ACL_APPEND_DATA},42{ACE_DELETE_CHILD, ACL_DELETE_CHILD},43{ACE_DELETE, ACL_DELETE},44{ACE_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},45{ACE_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},46{ACE_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},47{ACE_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},48{ACE_READ_ACL, ACL_READ_ACL},49{ACE_WRITE_ACL, ACL_WRITE_ACL},50{ACE_WRITE_OWNER, ACL_WRITE_OWNER},51{ACE_SYNCHRONIZE, ACL_SYNCHRONIZE},52{0, 0}};5354struct zfs2bsd flags[] = {{ACE_FILE_INHERIT_ACE,55ACL_ENTRY_FILE_INHERIT},56{ACE_DIRECTORY_INHERIT_ACE,57ACL_ENTRY_DIRECTORY_INHERIT},58{ACE_NO_PROPAGATE_INHERIT_ACE,59ACL_ENTRY_NO_PROPAGATE_INHERIT},60{ACE_INHERIT_ONLY_ACE,61ACL_ENTRY_INHERIT_ONLY},62{ACE_INHERITED_ACE,63ACL_ENTRY_INHERITED},64{ACE_SUCCESSFUL_ACCESS_ACE_FLAG,65ACL_ENTRY_SUCCESSFUL_ACCESS},66{ACE_FAILED_ACCESS_ACE_FLAG,67ACL_ENTRY_FAILED_ACCESS},68{0, 0}};6970static int71_bsd_from_zfs(uint32_t zfs, const struct zfs2bsd *table)72{73const struct zfs2bsd *tmp;74int bsd = 0;7576for (tmp = table; tmp->zb_zfs != 0; tmp++) {77if (zfs & tmp->zb_zfs)78bsd |= tmp->zb_bsd;79}8081return (bsd);82}8384static uint32_t85_zfs_from_bsd(int bsd, const struct zfs2bsd *table)86{87const struct zfs2bsd *tmp;88uint32_t zfs = 0;8990for (tmp = table; tmp->zb_bsd != 0; tmp++) {91if (bsd & tmp->zb_bsd)92zfs |= tmp->zb_zfs;93}9495return (zfs);96}9798int99acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries)100{101int i;102struct acl_entry *entry;103const ace_t *ace;104105if (nentries < 1) {106printf("acl_from_aces: empty ZFS ACL; returning EINVAL.\n");107return (EINVAL);108}109110if (nentries > ACL_MAX_ENTRIES) {111/*112* I believe it may happen only when moving a pool113* from SunOS to FreeBSD.114*/115printf("acl_from_aces: ZFS ACL too big to fit "116"into 'struct acl'; returning EINVAL.\n");117return (EINVAL);118}119120bzero(aclp, sizeof(*aclp));121aclp->acl_maxcnt = ACL_MAX_ENTRIES;122aclp->acl_cnt = nentries;123124for (i = 0; i < nentries; i++) {125entry = &(aclp->acl_entry[i]);126ace = &(aces[i]);127128if (ace->a_flags & ACE_OWNER)129entry->ae_tag = ACL_USER_OBJ;130else if (ace->a_flags & ACE_GROUP)131entry->ae_tag = ACL_GROUP_OBJ;132else if (ace->a_flags & ACE_EVERYONE)133entry->ae_tag = ACL_EVERYONE;134else if (ace->a_flags & ACE_IDENTIFIER_GROUP)135entry->ae_tag = ACL_GROUP;136else137entry->ae_tag = ACL_USER;138139if (entry->ae_tag == ACL_USER || entry->ae_tag == ACL_GROUP)140entry->ae_id = ace->a_who;141else142entry->ae_id = ACL_UNDEFINED_ID;143144entry->ae_perm = _bsd_from_zfs(ace->a_access_mask, perms);145entry->ae_flags = _bsd_from_zfs(ace->a_flags, flags);146147switch (ace->a_type) {148case ACE_ACCESS_ALLOWED_ACE_TYPE:149entry->ae_entry_type = ACL_ENTRY_TYPE_ALLOW;150break;151case ACE_ACCESS_DENIED_ACE_TYPE:152entry->ae_entry_type = ACL_ENTRY_TYPE_DENY;153break;154case ACE_SYSTEM_AUDIT_ACE_TYPE:155entry->ae_entry_type = ACL_ENTRY_TYPE_AUDIT;156break;157case ACE_SYSTEM_ALARM_ACE_TYPE:158entry->ae_entry_type = ACL_ENTRY_TYPE_ALARM;159break;160default:161panic("acl_from_aces: a_type is 0x%x", ace->a_type);162}163}164165return (0);166}167168void169aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp)170{171int i;172const struct acl_entry *entry;173ace_t *ace;174175bzero(aces, sizeof(*aces) * aclp->acl_cnt);176177*nentries = aclp->acl_cnt;178179for (i = 0; i < aclp->acl_cnt; i++) {180entry = &(aclp->acl_entry[i]);181ace = &(aces[i]);182183ace->a_who = entry->ae_id;184185if (entry->ae_tag == ACL_USER_OBJ)186ace->a_flags = ACE_OWNER;187else if (entry->ae_tag == ACL_GROUP_OBJ)188ace->a_flags = (ACE_GROUP | ACE_IDENTIFIER_GROUP);189else if (entry->ae_tag == ACL_GROUP)190ace->a_flags = ACE_IDENTIFIER_GROUP;191else if (entry->ae_tag == ACL_EVERYONE)192ace->a_flags = ACE_EVERYONE;193else /* ACL_USER */194ace->a_flags = 0;195196ace->a_access_mask = _zfs_from_bsd(entry->ae_perm, perms);197ace->a_flags |= _zfs_from_bsd(entry->ae_flags, flags);198199switch (entry->ae_entry_type) {200case ACL_ENTRY_TYPE_ALLOW:201ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;202break;203case ACL_ENTRY_TYPE_DENY:204ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;205break;206case ACL_ENTRY_TYPE_ALARM:207ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;208break;209case ACL_ENTRY_TYPE_AUDIT:210ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;211break;212default:213panic("aces_from_acl: ae_entry_type is 0x%x", entry->ae_entry_type);214}215}216}217218219