174432Sjedgar/* 290781Sjedgar * Copyright (c) 2001-2002 Chris D. Faulhaber 374432Sjedgar * All rights reserved. 474432Sjedgar * 574432Sjedgar * Redistribution and use in source and binary forms, with or without 674432Sjedgar * modification, are permitted provided that the following conditions 774432Sjedgar * are met: 874432Sjedgar * 1. Redistributions of source code must retain the above copyright 974432Sjedgar * notice, this list of conditions and the following disclaimer. 1074432Sjedgar * 2. Redistributions in binary form must reproduce the above copyright 1174432Sjedgar * notice, this list of conditions and the following disclaimer in the 1274432Sjedgar * documentation and/or other materials provided with the distribution. 1374432Sjedgar * 1474432Sjedgar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1574432Sjedgar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1674432Sjedgar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1774432Sjedgar * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1874432Sjedgar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1974432Sjedgar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2074432Sjedgar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2174432Sjedgar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2274432Sjedgar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2374432Sjedgar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2474432Sjedgar * SUCH DAMAGE. 2574432Sjedgar */ 2674432Sjedgar 2792986Sobrien#include <sys/cdefs.h> 2892986Sobrien__FBSDID("$FreeBSD$"); 2992986Sobrien 3074432Sjedgar#include <sys/types.h> 3175185Stmm#include "namespace.h" 3274432Sjedgar#include <sys/acl.h> 3375185Stmm#include "un-namespace.h" 3474432Sjedgar#include <errno.h> 3574432Sjedgar#include <string.h> 36194955Strasz#include <stdio.h> 3774432Sjedgar 38194955Strasz#include "acl_support.h" 39194955Strasz 40194955Straszstatic int 41194955Strasz_entry_matches(const acl_entry_t a, const acl_entry_t b) 42194955Strasz{ 43194955Strasz /* 44194955Strasz * There is a semantical difference here between NFSv4 and POSIX 45194955Strasz * draft ACLs. In POSIX, there may be only one entry for the particular 46194955Strasz * user or group. In NFSv4 ACL, there may be any number of them. We're 47194955Strasz * trying to be more specific here in that case. 48194955Strasz */ 49194955Strasz switch (_entry_brand(a)) { 50194955Strasz case ACL_BRAND_NFS4: 51194955Strasz if (a->ae_tag != b->ae_tag || a->ae_entry_type != b->ae_entry_type) 52194955Strasz return (0); 53194955Strasz 54194955Strasz /* If ae_ids matter, compare them as well. */ 55194955Strasz if (a->ae_tag == ACL_USER || a->ae_tag == ACL_GROUP) { 56194955Strasz if (a->ae_id != b->ae_id) 57194955Strasz return (0); 58194955Strasz } 59194955Strasz 60194955Strasz return (1); 61194955Strasz 62194955Strasz default: 63194955Strasz if ((a->ae_tag == b->ae_tag) && (a->ae_id == b->ae_id)) 64194955Strasz return (1); 65194955Strasz } 66194955Strasz 67194955Strasz return (0); 68194955Strasz} 69194955Strasz 7075928Sjedgar/* 7175928Sjedgar * acl_delete_entry() (23.4.9): remove the ACL entry indicated by entry_d 7275928Sjedgar * from acl. 7375928Sjedgar */ 7474432Sjedgarint 7574432Sjedgaracl_delete_entry(acl_t acl, acl_entry_t entry_d) 7674432Sjedgar{ 7775928Sjedgar struct acl *acl_int; 78200992Smarkus struct acl_entry entry_int; 79194955Strasz int i, j, found = 0; 8074432Sjedgar 8190781Sjedgar if (acl == NULL || entry_d == NULL) { 8274432Sjedgar errno = EINVAL; 8390781Sjedgar return (-1); 8474432Sjedgar } 8575928Sjedgar 8675928Sjedgar acl_int = &acl->ats_acl; 8775928Sjedgar 88194955Strasz if (_entry_brand(entry_d) != _acl_brand(acl)) { 89194955Strasz errno = EINVAL; 90194955Strasz return (-1); 91194955Strasz } 92194955Strasz 9375928Sjedgar if ((acl->ats_acl.acl_cnt < 1) || 9475928Sjedgar (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { 9575928Sjedgar errno = EINVAL; 9690781Sjedgar return (-1); 9775928Sjedgar } 98200992Smarkus 99200992Smarkus /* Use a local copy to prevent deletion of more than this entry */ 100200992Smarkus entry_int = *entry_d; 101200992Smarkus 102194955Strasz for (i = 0; i < acl->ats_acl.acl_cnt;) { 103200992Smarkus if (_entry_matches(&(acl->ats_acl.acl_entry[i]), &entry_int)) { 10474432Sjedgar /* ...shift the remaining entries... */ 105194955Strasz for (j = i; j < acl->ats_acl.acl_cnt - 1; ++j) 106194955Strasz acl->ats_acl.acl_entry[j] = 107194955Strasz acl->ats_acl.acl_entry[j+1]; 10874432Sjedgar /* ...drop the count and zero the unused entry... */ 10975928Sjedgar acl->ats_acl.acl_cnt--; 110194955Strasz bzero(&acl->ats_acl.acl_entry[j], 11175928Sjedgar sizeof(struct acl_entry)); 11275928Sjedgar acl->ats_cur_entry = 0; 113194955Strasz 114194955Strasz /* Continue with the loop to remove all maching entries. */ 115194955Strasz found = 1; 116194955Strasz } else 117194955Strasz i++; 11874432Sjedgar } 11974432Sjedgar 120194955Strasz if (found) 121194955Strasz return (0); 12274432Sjedgar 12374432Sjedgar errno = EINVAL; 12490781Sjedgar return (-1); 12574432Sjedgar} 126194955Strasz 127194955Straszint 128194955Straszacl_delete_entry_np(acl_t acl, int offset) 129194955Strasz{ 130194955Strasz struct acl *acl_int; 131194955Strasz int i; 132194955Strasz 133194955Strasz if (acl == NULL) { 134194955Strasz errno = EINVAL; 135194955Strasz return (-1); 136194955Strasz } 137194955Strasz 138194955Strasz acl_int = &acl->ats_acl; 139194955Strasz 140194955Strasz if (offset < 0 || offset >= acl_int->acl_cnt) { 141194955Strasz errno = EINVAL; 142194955Strasz return (-1); 143194955Strasz } 144194955Strasz 145194955Strasz if ((acl->ats_acl.acl_cnt < 1) || 146194955Strasz (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { 147194955Strasz errno = EINVAL; 148194955Strasz return (-1); 149194955Strasz } 150194955Strasz 151194955Strasz /* ...shift the remaining entries... */ 152194955Strasz for (i = offset; i < acl->ats_acl.acl_cnt - 1; ++i) 153194955Strasz acl->ats_acl.acl_entry[i] = 154194955Strasz acl->ats_acl.acl_entry[i+1]; 155194955Strasz /* ...drop the count and zero the unused entry... */ 156194955Strasz acl->ats_acl.acl_cnt--; 157194955Strasz bzero(&acl->ats_acl.acl_entry[i], 158194955Strasz sizeof(struct acl_entry)); 159194955Strasz acl->ats_cur_entry = 0; 160194955Strasz 161194955Strasz return (0); 162194955Strasz} 163