1194955Strasz/*- 2194955Strasz * Copyright (c) 2008, 2009 Edward Tomasz Napiera��a <trasz@FreeBSD.org> 3194955Strasz * All rights reserved. 4194955Strasz * 5194955Strasz * Redistribution and use in source and binary forms, with or without 6194955Strasz * modification, are permitted provided that the following conditions 7194955Strasz * are met: 8194955Strasz * 1. Redistributions of source code must retain the above copyright 9194955Strasz * notice, this list of conditions and the following disclaimer. 10194955Strasz * 2. Redistributions in binary form must reproduce the above copyright 11194955Strasz * notice, this list of conditions and the following disclaimer in the 12194955Strasz * documentation and/or other materials provided with the distribution. 13194955Strasz * 14194955Strasz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15194955Strasz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16194955Strasz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17194955Strasz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18194955Strasz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19194955Strasz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20194955Strasz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21194955Strasz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22194955Strasz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23194955Strasz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24194955Strasz * SUCH DAMAGE. 25194955Strasz */ 26194955Strasz 27194955Strasz#include <sys/cdefs.h> 28194955Strasz__FBSDID("$FreeBSD$"); 29194955Strasz 30194955Strasz#include <assert.h> 31194955Strasz#include <errno.h> 32194955Strasz#include <sys/acl.h> 33194955Strasz 34194955Strasz#include "acl_support.h" 35194955Strasz 36194955Strasz/* 37194955Strasz * An ugly detail of the implementation - fortunately not visible 38194955Strasz * to the API users - is the "branding": libc needs to keep track 39194955Strasz * of what "brand" ACL is: NFSv4, POSIX.1e or unknown. It happens 40194955Strasz * automatically - for example, during acl_get_file(3) ACL gets 41194955Strasz * branded according to the "type" argument; during acl_set_permset 42194955Strasz * ACL, if its brand is unknown it gets branded as NFSv4 if any of the 43194955Strasz * NFSv4 permissions that are not valid for POSIX.1e ACL are set etc. 44194955Strasz * Branding information is used for printing out the ACL (acl_to_text(3)), 45194955Strasz * veryfying acl_set_whatever arguments (checking against setting 46194955Strasz * bits that are valid only for NFSv4 in ACL branded as POSIX.1e) etc. 47194955Strasz */ 48194955Strasz 49194955Straszstatic acl_t 50194955Straszentry2acl(acl_entry_t entry) 51194955Strasz{ 52194955Strasz acl_t aclp; 53194955Strasz 54194955Strasz aclp = (acl_t)(((long)entry >> _ACL_T_ALIGNMENT_BITS) << _ACL_T_ALIGNMENT_BITS); 55194955Strasz 56194955Strasz return (aclp); 57194955Strasz} 58194955Strasz 59194955Strasz/* 60194955Strasz * Return brand of an ACL. 61194955Strasz */ 62194955Straszint 63194955Strasz_acl_brand(const acl_t acl) 64194955Strasz{ 65194955Strasz 66194955Strasz return (acl->ats_brand); 67194955Strasz} 68194955Strasz 69194955Straszint 70194955Strasz_entry_brand(const acl_entry_t entry) 71194955Strasz{ 72194955Strasz 73194955Strasz return (_acl_brand(entry2acl(entry))); 74194955Strasz} 75194955Strasz 76194955Strasz/* 77194955Strasz * Return 1, iff branding ACL as "brand" is ok. 78194955Strasz */ 79194955Straszint 80194955Strasz_acl_brand_may_be(const acl_t acl, int brand) 81194955Strasz{ 82194955Strasz 83194955Strasz if (_acl_brand(acl) == ACL_BRAND_UNKNOWN) 84194955Strasz return (1); 85194955Strasz 86194955Strasz if (_acl_brand(acl) == brand) 87194955Strasz return (1); 88194955Strasz 89194955Strasz return (0); 90194955Strasz} 91194955Strasz 92194955Straszint 93194955Strasz_entry_brand_may_be(const acl_entry_t entry, int brand) 94194955Strasz{ 95194955Strasz 96194955Strasz return (_acl_brand_may_be(entry2acl(entry), brand)); 97194955Strasz} 98194955Strasz 99194955Strasz/* 100194955Strasz * Brand ACL as "brand". 101194955Strasz */ 102194955Straszvoid 103194955Strasz_acl_brand_as(acl_t acl, int brand) 104194955Strasz{ 105194955Strasz 106194955Strasz assert(_acl_brand_may_be(acl, brand)); 107194955Strasz 108194955Strasz acl->ats_brand = brand; 109194955Strasz} 110194955Strasz 111194955Straszvoid 112194955Strasz_entry_brand_as(const acl_entry_t entry, int brand) 113194955Strasz{ 114194955Strasz 115194955Strasz _acl_brand_as(entry2acl(entry), brand); 116194955Strasz} 117194955Strasz 118194955Straszint 119194955Strasz_acl_type_not_valid_for_acl(const acl_t acl, acl_type_t type) 120194955Strasz{ 121194955Strasz 122194955Strasz switch (_acl_brand(acl)) { 123194955Strasz case ACL_BRAND_NFS4: 124194955Strasz if (type == ACL_TYPE_NFS4) 125194955Strasz return (0); 126194955Strasz break; 127194955Strasz 128194955Strasz case ACL_BRAND_POSIX: 129194955Strasz if (type == ACL_TYPE_ACCESS || type == ACL_TYPE_DEFAULT) 130194955Strasz return (0); 131194955Strasz break; 132208034Strasz 133208034Strasz case ACL_BRAND_UNKNOWN: 134208034Strasz return (0); 135194955Strasz } 136194955Strasz 137194955Strasz return (-1); 138194955Strasz} 139194955Strasz 140194955Straszvoid 141194955Strasz_acl_brand_from_type(acl_t acl, acl_type_t type) 142194955Strasz{ 143194955Strasz 144194955Strasz switch (type) { 145194955Strasz case ACL_TYPE_NFS4: 146194955Strasz _acl_brand_as(acl, ACL_BRAND_NFS4); 147194955Strasz break; 148194955Strasz case ACL_TYPE_ACCESS: 149194955Strasz case ACL_TYPE_DEFAULT: 150194955Strasz _acl_brand_as(acl, ACL_BRAND_POSIX); 151194955Strasz break; 152194955Strasz default: 153194955Strasz /* XXX: What to do here? */ 154194955Strasz break; 155194955Strasz } 156194955Strasz} 157194955Strasz 158194955Straszint 159194955Straszacl_get_brand_np(acl_t acl, int *brand_p) 160194955Strasz{ 161194955Strasz 162194955Strasz if (acl == NULL || brand_p == NULL) { 163194955Strasz errno = EINVAL; 164194955Strasz return (-1); 165194955Strasz } 166194955Strasz *brand_p = _acl_brand(acl); 167194955Strasz 168194955Strasz return (0); 169194955Strasz} 170