1aa015c8eSEdward Tomasz Napierala /*- 2*d915a14eSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*d915a14eSPedro F. Giffuni * 4aa015c8eSEdward Tomasz Napierala * Copyright (c) 2008, 2009 Edward Tomasz Napierała <trasz@FreeBSD.org> 5aa015c8eSEdward Tomasz Napierala * All rights reserved. 6aa015c8eSEdward Tomasz Napierala * 7aa015c8eSEdward Tomasz Napierala * Redistribution and use in source and binary forms, with or without 8aa015c8eSEdward Tomasz Napierala * modification, are permitted provided that the following conditions 9aa015c8eSEdward Tomasz Napierala * are met: 10aa015c8eSEdward Tomasz Napierala * 1. Redistributions of source code must retain the above copyright 11aa015c8eSEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer. 12aa015c8eSEdward Tomasz Napierala * 2. Redistributions in binary form must reproduce the above copyright 13aa015c8eSEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer in the 14aa015c8eSEdward Tomasz Napierala * documentation and/or other materials provided with the distribution. 15aa015c8eSEdward Tomasz Napierala * 16aa015c8eSEdward Tomasz Napierala * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17aa015c8eSEdward Tomasz Napierala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18aa015c8eSEdward Tomasz Napierala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19aa015c8eSEdward Tomasz Napierala * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20aa015c8eSEdward Tomasz Napierala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21aa015c8eSEdward Tomasz Napierala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22aa015c8eSEdward Tomasz Napierala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23aa015c8eSEdward Tomasz Napierala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24aa015c8eSEdward Tomasz Napierala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25aa015c8eSEdward Tomasz Napierala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26aa015c8eSEdward Tomasz Napierala * SUCH DAMAGE. 27aa015c8eSEdward Tomasz Napierala */ 28aa015c8eSEdward Tomasz Napierala 29aa015c8eSEdward Tomasz Napierala #include <sys/cdefs.h> 30aa015c8eSEdward Tomasz Napierala __FBSDID("$FreeBSD$"); 31aa015c8eSEdward Tomasz Napierala 32aa015c8eSEdward Tomasz Napierala #include <assert.h> 33aa015c8eSEdward Tomasz Napierala #include <errno.h> 34aa015c8eSEdward Tomasz Napierala #include <sys/acl.h> 35aa015c8eSEdward Tomasz Napierala 36aa015c8eSEdward Tomasz Napierala #include "acl_support.h" 37aa015c8eSEdward Tomasz Napierala 38aa015c8eSEdward Tomasz Napierala /* 39aa015c8eSEdward Tomasz Napierala * An ugly detail of the implementation - fortunately not visible 40aa015c8eSEdward Tomasz Napierala * to the API users - is the "branding": libc needs to keep track 41aa015c8eSEdward Tomasz Napierala * of what "brand" ACL is: NFSv4, POSIX.1e or unknown. It happens 42aa015c8eSEdward Tomasz Napierala * automatically - for example, during acl_get_file(3) ACL gets 43aa015c8eSEdward Tomasz Napierala * branded according to the "type" argument; during acl_set_permset 44aa015c8eSEdward Tomasz Napierala * ACL, if its brand is unknown it gets branded as NFSv4 if any of the 45aa015c8eSEdward Tomasz Napierala * NFSv4 permissions that are not valid for POSIX.1e ACL are set etc. 46aa015c8eSEdward Tomasz Napierala * Branding information is used for printing out the ACL (acl_to_text(3)), 47aa015c8eSEdward Tomasz Napierala * veryfying acl_set_whatever arguments (checking against setting 48aa015c8eSEdward Tomasz Napierala * bits that are valid only for NFSv4 in ACL branded as POSIX.1e) etc. 49aa015c8eSEdward Tomasz Napierala */ 50aa015c8eSEdward Tomasz Napierala 51aa015c8eSEdward Tomasz Napierala static acl_t 52aa015c8eSEdward Tomasz Napierala entry2acl(acl_entry_t entry) 53aa015c8eSEdward Tomasz Napierala { 54aa015c8eSEdward Tomasz Napierala acl_t aclp; 55aa015c8eSEdward Tomasz Napierala 56aa015c8eSEdward Tomasz Napierala aclp = (acl_t)(((long)entry >> _ACL_T_ALIGNMENT_BITS) << _ACL_T_ALIGNMENT_BITS); 57aa015c8eSEdward Tomasz Napierala 58aa015c8eSEdward Tomasz Napierala return (aclp); 59aa015c8eSEdward Tomasz Napierala } 60aa015c8eSEdward Tomasz Napierala 61aa015c8eSEdward Tomasz Napierala /* 62aa015c8eSEdward Tomasz Napierala * Return brand of an ACL. 63aa015c8eSEdward Tomasz Napierala */ 64aa015c8eSEdward Tomasz Napierala int 65aa015c8eSEdward Tomasz Napierala _acl_brand(const acl_t acl) 66aa015c8eSEdward Tomasz Napierala { 67aa015c8eSEdward Tomasz Napierala 68aa015c8eSEdward Tomasz Napierala return (acl->ats_brand); 69aa015c8eSEdward Tomasz Napierala } 70aa015c8eSEdward Tomasz Napierala 71aa015c8eSEdward Tomasz Napierala int 72aa015c8eSEdward Tomasz Napierala _entry_brand(const acl_entry_t entry) 73aa015c8eSEdward Tomasz Napierala { 74aa015c8eSEdward Tomasz Napierala 75aa015c8eSEdward Tomasz Napierala return (_acl_brand(entry2acl(entry))); 76aa015c8eSEdward Tomasz Napierala } 77aa015c8eSEdward Tomasz Napierala 78aa015c8eSEdward Tomasz Napierala /* 79aa015c8eSEdward Tomasz Napierala * Return 1, iff branding ACL as "brand" is ok. 80aa015c8eSEdward Tomasz Napierala */ 81aa015c8eSEdward Tomasz Napierala int 82aa015c8eSEdward Tomasz Napierala _acl_brand_may_be(const acl_t acl, int brand) 83aa015c8eSEdward Tomasz Napierala { 84aa015c8eSEdward Tomasz Napierala 85aa015c8eSEdward Tomasz Napierala if (_acl_brand(acl) == ACL_BRAND_UNKNOWN) 86aa015c8eSEdward Tomasz Napierala return (1); 87aa015c8eSEdward Tomasz Napierala 88aa015c8eSEdward Tomasz Napierala if (_acl_brand(acl) == brand) 89aa015c8eSEdward Tomasz Napierala return (1); 90aa015c8eSEdward Tomasz Napierala 91aa015c8eSEdward Tomasz Napierala return (0); 92aa015c8eSEdward Tomasz Napierala } 93aa015c8eSEdward Tomasz Napierala 94aa015c8eSEdward Tomasz Napierala int 95aa015c8eSEdward Tomasz Napierala _entry_brand_may_be(const acl_entry_t entry, int brand) 96aa015c8eSEdward Tomasz Napierala { 97aa015c8eSEdward Tomasz Napierala 98aa015c8eSEdward Tomasz Napierala return (_acl_brand_may_be(entry2acl(entry), brand)); 99aa015c8eSEdward Tomasz Napierala } 100aa015c8eSEdward Tomasz Napierala 101aa015c8eSEdward Tomasz Napierala /* 102aa015c8eSEdward Tomasz Napierala * Brand ACL as "brand". 103aa015c8eSEdward Tomasz Napierala */ 104aa015c8eSEdward Tomasz Napierala void 105aa015c8eSEdward Tomasz Napierala _acl_brand_as(acl_t acl, int brand) 106aa015c8eSEdward Tomasz Napierala { 107aa015c8eSEdward Tomasz Napierala 108aa015c8eSEdward Tomasz Napierala assert(_acl_brand_may_be(acl, brand)); 109aa015c8eSEdward Tomasz Napierala 110aa015c8eSEdward Tomasz Napierala acl->ats_brand = brand; 111aa015c8eSEdward Tomasz Napierala } 112aa015c8eSEdward Tomasz Napierala 113aa015c8eSEdward Tomasz Napierala void 114aa015c8eSEdward Tomasz Napierala _entry_brand_as(const acl_entry_t entry, int brand) 115aa015c8eSEdward Tomasz Napierala { 116aa015c8eSEdward Tomasz Napierala 117aa015c8eSEdward Tomasz Napierala _acl_brand_as(entry2acl(entry), brand); 118aa015c8eSEdward Tomasz Napierala } 119aa015c8eSEdward Tomasz Napierala 120aa015c8eSEdward Tomasz Napierala int 121aa015c8eSEdward Tomasz Napierala _acl_type_not_valid_for_acl(const acl_t acl, acl_type_t type) 122aa015c8eSEdward Tomasz Napierala { 123aa015c8eSEdward Tomasz Napierala 124aa015c8eSEdward Tomasz Napierala switch (_acl_brand(acl)) { 125aa015c8eSEdward Tomasz Napierala case ACL_BRAND_NFS4: 126aa015c8eSEdward Tomasz Napierala if (type == ACL_TYPE_NFS4) 127aa015c8eSEdward Tomasz Napierala return (0); 128aa015c8eSEdward Tomasz Napierala break; 129aa015c8eSEdward Tomasz Napierala 130aa015c8eSEdward Tomasz Napierala case ACL_BRAND_POSIX: 131aa015c8eSEdward Tomasz Napierala if (type == ACL_TYPE_ACCESS || type == ACL_TYPE_DEFAULT) 132aa015c8eSEdward Tomasz Napierala return (0); 133aa015c8eSEdward Tomasz Napierala break; 1341ccc2ae3SEdward Tomasz Napierala 1351ccc2ae3SEdward Tomasz Napierala case ACL_BRAND_UNKNOWN: 1361ccc2ae3SEdward Tomasz Napierala return (0); 137aa015c8eSEdward Tomasz Napierala } 138aa015c8eSEdward Tomasz Napierala 139aa015c8eSEdward Tomasz Napierala return (-1); 140aa015c8eSEdward Tomasz Napierala } 141aa015c8eSEdward Tomasz Napierala 142aa015c8eSEdward Tomasz Napierala void 143aa015c8eSEdward Tomasz Napierala _acl_brand_from_type(acl_t acl, acl_type_t type) 144aa015c8eSEdward Tomasz Napierala { 145aa015c8eSEdward Tomasz Napierala 146aa015c8eSEdward Tomasz Napierala switch (type) { 147aa015c8eSEdward Tomasz Napierala case ACL_TYPE_NFS4: 148aa015c8eSEdward Tomasz Napierala _acl_brand_as(acl, ACL_BRAND_NFS4); 149aa015c8eSEdward Tomasz Napierala break; 150aa015c8eSEdward Tomasz Napierala case ACL_TYPE_ACCESS: 151aa015c8eSEdward Tomasz Napierala case ACL_TYPE_DEFAULT: 152aa015c8eSEdward Tomasz Napierala _acl_brand_as(acl, ACL_BRAND_POSIX); 153aa015c8eSEdward Tomasz Napierala break; 154aa015c8eSEdward Tomasz Napierala default: 155aa015c8eSEdward Tomasz Napierala /* XXX: What to do here? */ 156aa015c8eSEdward Tomasz Napierala break; 157aa015c8eSEdward Tomasz Napierala } 158aa015c8eSEdward Tomasz Napierala } 159aa015c8eSEdward Tomasz Napierala 160aa015c8eSEdward Tomasz Napierala int 161aa015c8eSEdward Tomasz Napierala acl_get_brand_np(acl_t acl, int *brand_p) 162aa015c8eSEdward Tomasz Napierala { 163aa015c8eSEdward Tomasz Napierala 164aa015c8eSEdward Tomasz Napierala if (acl == NULL || brand_p == NULL) { 165aa015c8eSEdward Tomasz Napierala errno = EINVAL; 166aa015c8eSEdward Tomasz Napierala return (-1); 167aa015c8eSEdward Tomasz Napierala } 168aa015c8eSEdward Tomasz Napierala *brand_p = _acl_brand(acl); 169aa015c8eSEdward Tomasz Napierala 170aa015c8eSEdward Tomasz Napierala return (0); 171aa015c8eSEdward Tomasz Napierala } 172