1*d915a14eSPedro F. Giffuni /*- 2*d915a14eSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*d915a14eSPedro F. Giffuni * 4e76872c1SChris D. Faulhaber * Copyright (c) 2001-2002 Chris D. Faulhaber 514721edaSChris D. Faulhaber * All rights reserved. 614721edaSChris D. Faulhaber * 714721edaSChris D. Faulhaber * Redistribution and use in source and binary forms, with or without 814721edaSChris D. Faulhaber * modification, are permitted provided that the following conditions 914721edaSChris D. Faulhaber * are met: 1014721edaSChris D. Faulhaber * 1. Redistributions of source code must retain the above copyright 1114721edaSChris D. Faulhaber * notice, this list of conditions and the following disclaimer. 1214721edaSChris D. Faulhaber * 2. Redistributions in binary form must reproduce the above copyright 1314721edaSChris D. Faulhaber * notice, this list of conditions and the following disclaimer in the 1414721edaSChris D. Faulhaber * documentation and/or other materials provided with the distribution. 1514721edaSChris D. Faulhaber * 1614721edaSChris D. Faulhaber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1714721edaSChris D. Faulhaber * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1814721edaSChris D. Faulhaber * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1914721edaSChris D. Faulhaber * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2014721edaSChris D. Faulhaber * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2114721edaSChris D. Faulhaber * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2214721edaSChris D. Faulhaber * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2314721edaSChris D. Faulhaber * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2414721edaSChris D. Faulhaber * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2514721edaSChris D. Faulhaber * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2614721edaSChris D. Faulhaber * SUCH DAMAGE. 2714721edaSChris D. Faulhaber */ 2814721edaSChris D. Faulhaber 29333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 30333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 31333fc21eSDavid E. O'Brien 3214721edaSChris D. Faulhaber #include <sys/types.h> 337bd44e92SThomas Moestl #include "namespace.h" 3414721edaSChris D. Faulhaber #include <sys/acl.h> 357bd44e92SThomas Moestl #include "un-namespace.h" 3614721edaSChris D. Faulhaber #include <errno.h> 3714721edaSChris D. Faulhaber #include <string.h> 38aa015c8eSEdward Tomasz Napierala #include <stdio.h> 39aa015c8eSEdward Tomasz Napierala 40aa015c8eSEdward Tomasz Napierala #include "acl_support.h" 41aa015c8eSEdward Tomasz Napierala 42aa015c8eSEdward Tomasz Napierala static int 43aa015c8eSEdward Tomasz Napierala _entry_matches(const acl_entry_t a, const acl_entry_t b) 44aa015c8eSEdward Tomasz Napierala { 45aa015c8eSEdward Tomasz Napierala /* 46aa015c8eSEdward Tomasz Napierala * There is a semantical difference here between NFSv4 and POSIX 47aa015c8eSEdward Tomasz Napierala * draft ACLs. In POSIX, there may be only one entry for the particular 48aa015c8eSEdward Tomasz Napierala * user or group. In NFSv4 ACL, there may be any number of them. We're 49aa015c8eSEdward Tomasz Napierala * trying to be more specific here in that case. 50aa015c8eSEdward Tomasz Napierala */ 51aa015c8eSEdward Tomasz Napierala switch (_entry_brand(a)) { 52aa015c8eSEdward Tomasz Napierala case ACL_BRAND_NFS4: 53aa015c8eSEdward Tomasz Napierala if (a->ae_tag != b->ae_tag || a->ae_entry_type != b->ae_entry_type) 54aa015c8eSEdward Tomasz Napierala return (0); 55aa015c8eSEdward Tomasz Napierala 56aa015c8eSEdward Tomasz Napierala /* If ae_ids matter, compare them as well. */ 57aa015c8eSEdward Tomasz Napierala if (a->ae_tag == ACL_USER || a->ae_tag == ACL_GROUP) { 58aa015c8eSEdward Tomasz Napierala if (a->ae_id != b->ae_id) 59aa015c8eSEdward Tomasz Napierala return (0); 60aa015c8eSEdward Tomasz Napierala } 61aa015c8eSEdward Tomasz Napierala 62aa015c8eSEdward Tomasz Napierala return (1); 63aa015c8eSEdward Tomasz Napierala 64aa015c8eSEdward Tomasz Napierala default: 65aa015c8eSEdward Tomasz Napierala if ((a->ae_tag == b->ae_tag) && (a->ae_id == b->ae_id)) 66aa015c8eSEdward Tomasz Napierala return (1); 67aa015c8eSEdward Tomasz Napierala } 68aa015c8eSEdward Tomasz Napierala 69aa015c8eSEdward Tomasz Napierala return (0); 70aa015c8eSEdward Tomasz Napierala } 7114721edaSChris D. Faulhaber 720f626307SChris D. Faulhaber /* 730f626307SChris D. Faulhaber * acl_delete_entry() (23.4.9): remove the ACL entry indicated by entry_d 740f626307SChris D. Faulhaber * from acl. 750f626307SChris D. Faulhaber */ 7614721edaSChris D. Faulhaber int 7714721edaSChris D. Faulhaber acl_delete_entry(acl_t acl, acl_entry_t entry_d) 7814721edaSChris D. Faulhaber { 790f626307SChris D. Faulhaber struct acl *acl_int; 8078da985fSMarkus Brueffer struct acl_entry entry_int; 81aa015c8eSEdward Tomasz Napierala int i, j, found = 0; 8214721edaSChris D. Faulhaber 83e76872c1SChris D. Faulhaber if (acl == NULL || entry_d == NULL) { 8414721edaSChris D. Faulhaber errno = EINVAL; 85e76872c1SChris D. Faulhaber return (-1); 8614721edaSChris D. Faulhaber } 870f626307SChris D. Faulhaber 880f626307SChris D. Faulhaber acl_int = &acl->ats_acl; 890f626307SChris D. Faulhaber 90aa015c8eSEdward Tomasz Napierala if (_entry_brand(entry_d) != _acl_brand(acl)) { 91aa015c8eSEdward Tomasz Napierala errno = EINVAL; 92aa015c8eSEdward Tomasz Napierala return (-1); 93aa015c8eSEdward Tomasz Napierala } 94aa015c8eSEdward Tomasz Napierala 950f626307SChris D. Faulhaber if ((acl->ats_acl.acl_cnt < 1) || 960f626307SChris D. Faulhaber (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { 970f626307SChris D. Faulhaber errno = EINVAL; 98e76872c1SChris D. Faulhaber return (-1); 990f626307SChris D. Faulhaber } 10078da985fSMarkus Brueffer 10178da985fSMarkus Brueffer /* Use a local copy to prevent deletion of more than this entry */ 10278da985fSMarkus Brueffer entry_int = *entry_d; 10378da985fSMarkus Brueffer 104aa015c8eSEdward Tomasz Napierala for (i = 0; i < acl->ats_acl.acl_cnt;) { 10578da985fSMarkus Brueffer if (_entry_matches(&(acl->ats_acl.acl_entry[i]), &entry_int)) { 10614721edaSChris D. Faulhaber /* ...shift the remaining entries... */ 107aa015c8eSEdward Tomasz Napierala for (j = i; j < acl->ats_acl.acl_cnt - 1; ++j) 108aa015c8eSEdward Tomasz Napierala acl->ats_acl.acl_entry[j] = 109aa015c8eSEdward Tomasz Napierala acl->ats_acl.acl_entry[j+1]; 110aa015c8eSEdward Tomasz Napierala /* ...drop the count and zero the unused entry... */ 111aa015c8eSEdward Tomasz Napierala acl->ats_acl.acl_cnt--; 112aa015c8eSEdward Tomasz Napierala bzero(&acl->ats_acl.acl_entry[j], 113aa015c8eSEdward Tomasz Napierala sizeof(struct acl_entry)); 114aa015c8eSEdward Tomasz Napierala acl->ats_cur_entry = 0; 115aa015c8eSEdward Tomasz Napierala 11632223c1bSPedro F. Giffuni /* Continue with the loop to remove all matching entries. */ 117aa015c8eSEdward Tomasz Napierala found = 1; 118aa015c8eSEdward Tomasz Napierala } else 119aa015c8eSEdward Tomasz Napierala i++; 120aa015c8eSEdward Tomasz Napierala } 121aa015c8eSEdward Tomasz Napierala 122aa015c8eSEdward Tomasz Napierala if (found) 123aa015c8eSEdward Tomasz Napierala return (0); 124aa015c8eSEdward Tomasz Napierala 125aa015c8eSEdward Tomasz Napierala errno = EINVAL; 126aa015c8eSEdward Tomasz Napierala return (-1); 127aa015c8eSEdward Tomasz Napierala } 128aa015c8eSEdward Tomasz Napierala 129aa015c8eSEdward Tomasz Napierala int 130aa015c8eSEdward Tomasz Napierala acl_delete_entry_np(acl_t acl, int offset) 131aa015c8eSEdward Tomasz Napierala { 132aa015c8eSEdward Tomasz Napierala struct acl *acl_int; 133aa015c8eSEdward Tomasz Napierala int i; 134aa015c8eSEdward Tomasz Napierala 135aa015c8eSEdward Tomasz Napierala if (acl == NULL) { 136aa015c8eSEdward Tomasz Napierala errno = EINVAL; 137aa015c8eSEdward Tomasz Napierala return (-1); 138aa015c8eSEdward Tomasz Napierala } 139aa015c8eSEdward Tomasz Napierala 140aa015c8eSEdward Tomasz Napierala acl_int = &acl->ats_acl; 141aa015c8eSEdward Tomasz Napierala 142aa015c8eSEdward Tomasz Napierala if (offset < 0 || offset >= acl_int->acl_cnt) { 143aa015c8eSEdward Tomasz Napierala errno = EINVAL; 144aa015c8eSEdward Tomasz Napierala return (-1); 145aa015c8eSEdward Tomasz Napierala } 146aa015c8eSEdward Tomasz Napierala 147aa015c8eSEdward Tomasz Napierala if ((acl->ats_acl.acl_cnt < 1) || 148aa015c8eSEdward Tomasz Napierala (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { 149aa015c8eSEdward Tomasz Napierala errno = EINVAL; 150aa015c8eSEdward Tomasz Napierala return (-1); 151aa015c8eSEdward Tomasz Napierala } 152aa015c8eSEdward Tomasz Napierala 153aa015c8eSEdward Tomasz Napierala /* ...shift the remaining entries... */ 154aa015c8eSEdward Tomasz Napierala for (i = offset; i < acl->ats_acl.acl_cnt - 1; ++i) 1550f626307SChris D. Faulhaber acl->ats_acl.acl_entry[i] = 156ff5fe653SJacques Vidrine acl->ats_acl.acl_entry[i+1]; 15714721edaSChris D. Faulhaber /* ...drop the count and zero the unused entry... */ 1580f626307SChris D. Faulhaber acl->ats_acl.acl_cnt--; 1590f626307SChris D. Faulhaber bzero(&acl->ats_acl.acl_entry[i], 1600f626307SChris D. Faulhaber sizeof(struct acl_entry)); 1610f626307SChris D. Faulhaber acl->ats_cur_entry = 0; 162aa015c8eSEdward Tomasz Napierala 163e76872c1SChris D. Faulhaber return (0); 16414721edaSChris D. Faulhaber } 165