114721edaSChris D. Faulhaber /* 2e76872c1SChris D. Faulhaber * Copyright (c) 2001-2002 Chris D. Faulhaber 314721edaSChris D. Faulhaber * All rights reserved. 414721edaSChris D. Faulhaber * 514721edaSChris D. Faulhaber * Redistribution and use in source and binary forms, with or without 614721edaSChris D. Faulhaber * modification, are permitted provided that the following conditions 714721edaSChris D. Faulhaber * are met: 814721edaSChris D. Faulhaber * 1. Redistributions of source code must retain the above copyright 914721edaSChris D. Faulhaber * notice, this list of conditions and the following disclaimer. 1014721edaSChris D. Faulhaber * 2. Redistributions in binary form must reproduce the above copyright 1114721edaSChris D. Faulhaber * notice, this list of conditions and the following disclaimer in the 1214721edaSChris D. Faulhaber * documentation and/or other materials provided with the distribution. 1314721edaSChris D. Faulhaber * 1414721edaSChris D. Faulhaber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1514721edaSChris D. Faulhaber * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1614721edaSChris D. Faulhaber * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1714721edaSChris D. Faulhaber * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1814721edaSChris D. Faulhaber * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1914721edaSChris D. Faulhaber * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2014721edaSChris D. Faulhaber * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2114721edaSChris D. Faulhaber * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2214721edaSChris D. Faulhaber * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2314721edaSChris D. Faulhaber * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2414721edaSChris D. Faulhaber * SUCH DAMAGE. 2514721edaSChris D. Faulhaber */ 2614721edaSChris D. Faulhaber 27333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 28333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 29333fc21eSDavid E. O'Brien 3014721edaSChris D. Faulhaber #include <sys/types.h> 317bd44e92SThomas Moestl #include "namespace.h" 3214721edaSChris D. Faulhaber #include <sys/acl.h> 337bd44e92SThomas Moestl #include "un-namespace.h" 3414721edaSChris D. Faulhaber #include <errno.h> 3514721edaSChris D. Faulhaber #include <string.h> 36aa015c8eSEdward Tomasz Napierala #include <stdio.h> 37aa015c8eSEdward Tomasz Napierala 38aa015c8eSEdward Tomasz Napierala #include "acl_support.h" 39aa015c8eSEdward Tomasz Napierala 40aa015c8eSEdward Tomasz Napierala static int 41aa015c8eSEdward Tomasz Napierala _entry_matches(const acl_entry_t a, const acl_entry_t b) 42aa015c8eSEdward Tomasz Napierala { 43aa015c8eSEdward Tomasz Napierala /* 44aa015c8eSEdward Tomasz Napierala * There is a semantical difference here between NFSv4 and POSIX 45aa015c8eSEdward Tomasz Napierala * draft ACLs. In POSIX, there may be only one entry for the particular 46aa015c8eSEdward Tomasz Napierala * user or group. In NFSv4 ACL, there may be any number of them. We're 47aa015c8eSEdward Tomasz Napierala * trying to be more specific here in that case. 48aa015c8eSEdward Tomasz Napierala */ 49aa015c8eSEdward Tomasz Napierala switch (_entry_brand(a)) { 50aa015c8eSEdward Tomasz Napierala case ACL_BRAND_NFS4: 51aa015c8eSEdward Tomasz Napierala if (a->ae_tag != b->ae_tag || a->ae_entry_type != b->ae_entry_type) 52aa015c8eSEdward Tomasz Napierala return (0); 53aa015c8eSEdward Tomasz Napierala 54aa015c8eSEdward Tomasz Napierala /* If ae_ids matter, compare them as well. */ 55aa015c8eSEdward Tomasz Napierala if (a->ae_tag == ACL_USER || a->ae_tag == ACL_GROUP) { 56aa015c8eSEdward Tomasz Napierala if (a->ae_id != b->ae_id) 57aa015c8eSEdward Tomasz Napierala return (0); 58aa015c8eSEdward Tomasz Napierala } 59aa015c8eSEdward Tomasz Napierala 60aa015c8eSEdward Tomasz Napierala return (1); 61aa015c8eSEdward Tomasz Napierala 62aa015c8eSEdward Tomasz Napierala default: 63aa015c8eSEdward Tomasz Napierala if ((a->ae_tag == b->ae_tag) && (a->ae_id == b->ae_id)) 64aa015c8eSEdward Tomasz Napierala return (1); 65aa015c8eSEdward Tomasz Napierala } 66aa015c8eSEdward Tomasz Napierala 67aa015c8eSEdward Tomasz Napierala return (0); 68aa015c8eSEdward Tomasz Napierala } 6914721edaSChris D. Faulhaber 700f626307SChris D. Faulhaber /* 710f626307SChris D. Faulhaber * acl_delete_entry() (23.4.9): remove the ACL entry indicated by entry_d 720f626307SChris D. Faulhaber * from acl. 730f626307SChris D. Faulhaber */ 7414721edaSChris D. Faulhaber int 7514721edaSChris D. Faulhaber acl_delete_entry(acl_t acl, acl_entry_t entry_d) 7614721edaSChris D. Faulhaber { 770f626307SChris D. Faulhaber struct acl *acl_int; 78aa015c8eSEdward Tomasz Napierala int i, j, found = 0; 7914721edaSChris D. Faulhaber 80e76872c1SChris D. Faulhaber if (acl == NULL || entry_d == NULL) { 8114721edaSChris D. Faulhaber errno = EINVAL; 82e76872c1SChris D. Faulhaber return (-1); 8314721edaSChris D. Faulhaber } 840f626307SChris D. Faulhaber 850f626307SChris D. Faulhaber acl_int = &acl->ats_acl; 860f626307SChris D. Faulhaber 87aa015c8eSEdward Tomasz Napierala if (_entry_brand(entry_d) != _acl_brand(acl)) { 88aa015c8eSEdward Tomasz Napierala errno = EINVAL; 89aa015c8eSEdward Tomasz Napierala return (-1); 90aa015c8eSEdward Tomasz Napierala } 91aa015c8eSEdward Tomasz Napierala 920f626307SChris D. Faulhaber if ((acl->ats_acl.acl_cnt < 1) || 930f626307SChris D. Faulhaber (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { 940f626307SChris D. Faulhaber errno = EINVAL; 95e76872c1SChris D. Faulhaber return (-1); 960f626307SChris D. Faulhaber } 97aa015c8eSEdward Tomasz Napierala for (i = 0; i < acl->ats_acl.acl_cnt;) { 98aa015c8eSEdward Tomasz Napierala if (_entry_matches(&(acl->ats_acl.acl_entry[i]), entry_d)) { 9914721edaSChris D. Faulhaber /* ...shift the remaining entries... */ 100aa015c8eSEdward Tomasz Napierala for (j = i; j < acl->ats_acl.acl_cnt - 1; ++j) 101aa015c8eSEdward Tomasz Napierala acl->ats_acl.acl_entry[j] = 102aa015c8eSEdward Tomasz Napierala acl->ats_acl.acl_entry[j+1]; 103aa015c8eSEdward Tomasz Napierala /* ...drop the count and zero the unused entry... */ 104aa015c8eSEdward Tomasz Napierala acl->ats_acl.acl_cnt--; 105aa015c8eSEdward Tomasz Napierala bzero(&acl->ats_acl.acl_entry[j], 106aa015c8eSEdward Tomasz Napierala sizeof(struct acl_entry)); 107aa015c8eSEdward Tomasz Napierala acl->ats_cur_entry = 0; 108aa015c8eSEdward Tomasz Napierala 109aa015c8eSEdward Tomasz Napierala /* Continue with the loop to remove all maching entries. */ 110aa015c8eSEdward Tomasz Napierala found = 1; 111aa015c8eSEdward Tomasz Napierala } else 112aa015c8eSEdward Tomasz Napierala i++; 113aa015c8eSEdward Tomasz Napierala } 114aa015c8eSEdward Tomasz Napierala 115aa015c8eSEdward Tomasz Napierala if (found) 116aa015c8eSEdward Tomasz Napierala return (0); 117aa015c8eSEdward Tomasz Napierala 118aa015c8eSEdward Tomasz Napierala errno = EINVAL; 119aa015c8eSEdward Tomasz Napierala return (-1); 120aa015c8eSEdward Tomasz Napierala } 121aa015c8eSEdward Tomasz Napierala 122aa015c8eSEdward Tomasz Napierala int 123aa015c8eSEdward Tomasz Napierala acl_delete_entry_np(acl_t acl, int offset) 124aa015c8eSEdward Tomasz Napierala { 125aa015c8eSEdward Tomasz Napierala struct acl *acl_int; 126aa015c8eSEdward Tomasz Napierala int i; 127aa015c8eSEdward Tomasz Napierala 128aa015c8eSEdward Tomasz Napierala if (acl == NULL) { 129aa015c8eSEdward Tomasz Napierala errno = EINVAL; 130aa015c8eSEdward Tomasz Napierala return (-1); 131aa015c8eSEdward Tomasz Napierala } 132aa015c8eSEdward Tomasz Napierala 133aa015c8eSEdward Tomasz Napierala acl_int = &acl->ats_acl; 134aa015c8eSEdward Tomasz Napierala 135aa015c8eSEdward Tomasz Napierala if (offset < 0 || offset >= acl_int->acl_cnt) { 136aa015c8eSEdward Tomasz Napierala errno = EINVAL; 137aa015c8eSEdward Tomasz Napierala return (-1); 138aa015c8eSEdward Tomasz Napierala } 139aa015c8eSEdward Tomasz Napierala 140aa015c8eSEdward Tomasz Napierala if ((acl->ats_acl.acl_cnt < 1) || 141aa015c8eSEdward Tomasz Napierala (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { 142aa015c8eSEdward Tomasz Napierala errno = EINVAL; 143aa015c8eSEdward Tomasz Napierala return (-1); 144aa015c8eSEdward Tomasz Napierala } 145aa015c8eSEdward Tomasz Napierala 146aa015c8eSEdward Tomasz Napierala /* ...shift the remaining entries... */ 147aa015c8eSEdward Tomasz Napierala for (i = offset; i < acl->ats_acl.acl_cnt - 1; ++i) 1480f626307SChris D. Faulhaber acl->ats_acl.acl_entry[i] = 149ff5fe653SJacques Vidrine acl->ats_acl.acl_entry[i+1]; 15014721edaSChris D. Faulhaber /* ...drop the count and zero the unused entry... */ 1510f626307SChris D. Faulhaber acl->ats_acl.acl_cnt--; 1520f626307SChris D. Faulhaber bzero(&acl->ats_acl.acl_entry[i], 1530f626307SChris D. Faulhaber sizeof(struct acl_entry)); 1540f626307SChris D. Faulhaber acl->ats_cur_entry = 0; 155aa015c8eSEdward Tomasz Napierala 156e76872c1SChris D. Faulhaber return (0); 15714721edaSChris D. Faulhaber } 158