192108Sphk/*- 292108Sphk * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 392108Sphk * 492108Sphk * Copyright (c) 2001-2002 Chris D. Faulhaber 592108Sphk * All rights reserved. 692108Sphk * 792108Sphk * Redistribution and use in source and binary forms, with or without 892108Sphk * modification, are permitted provided that the following conditions 992108Sphk * are met: 1092108Sphk * 1. Redistributions of source code must retain the above copyright 1192108Sphk * notice, this list of conditions and the following disclaimer. 1292108Sphk * 2. Redistributions in binary form must reproduce the above copyright 1392108Sphk * notice, this list of conditions and the following disclaimer in the 1492108Sphk * documentation and/or other materials provided with the distribution. 1592108Sphk * 1692108Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1792108Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1892108Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1992108Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2092108Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2192108Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2292108Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2392108Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2492108Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2592108Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2692108Sphk * SUCH DAMAGE. 2792108Sphk */ 2892108Sphk 2992108Sphk#include <sys/cdefs.h> 3092108Sphk#if 0 3192108Sphk__FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_delete_entry.c 326193 2017-11-25 17:12:48Z pfg $"); 3292108Sphk#else 3392108Sphk__RCSID("$NetBSD: acl_delete_entry.c,v 1.1 2020/05/16 18:31:47 christos Exp $"); 3492108Sphk#endif 3592108Sphk 3692108Sphk#include "namespace.h" 3792108Sphk#include <sys/types.h> 3892108Sphk#include <sys/acl.h> 3992108Sphk#include <errno.h> 4092108Sphk#include <string.h> 4192108Sphk#include <stdio.h> 4292108Sphk 4392108Sphk#include "acl_support.h" 4492108Sphk 4592108Sphkstatic int 4692108Sphk_entry_matches(const acl_entry_t a, const acl_entry_t b) 4792108Sphk{ 4892108Sphk /* 4992108Sphk * There is a semantical difference here between NFSv4 and POSIX 5092108Sphk * draft ACLs. In POSIX, there may be only one entry for the particular 5192108Sphk * user or group. In NFSv4 ACL, there may be any number of them. We're 5292108Sphk * trying to be more specific here in that case. 5392108Sphk */ 5492108Sphk switch (_entry_brand(a)) { 5592108Sphk case ACL_BRAND_NFS4: 5692108Sphk if (a->ae_tag != b->ae_tag || a->ae_entry_type != b->ae_entry_type) 5792108Sphk return (0); 5892108Sphk 5992108Sphk /* If ae_ids matter, compare them as well. */ 6092108Sphk if (a->ae_tag == ACL_USER || a->ae_tag == ACL_GROUP) { 6192108Sphk if (a->ae_id != b->ae_id) 6292108Sphk return (0); 6392108Sphk } 6492108Sphk 6592108Sphk return (1); 6692108Sphk 6792108Sphk default: 6892108Sphk if ((a->ae_tag == b->ae_tag) && (a->ae_id == b->ae_id)) 6992108Sphk return (1); 7092108Sphk } 7192108Sphk 7292108Sphk return (0); 7392108Sphk} 7492108Sphk 7592108Sphk/* 7692108Sphk * acl_delete_entry() (23.4.9): remove the ACL entry indicated by entry_d 7792108Sphk * from acl. 7892108Sphk */ 7992108Sphkint 8092108Sphkacl_delete_entry(acl_t acl, acl_entry_t entry_d) 8192108Sphk{ 8292108Sphk struct acl_entry entry_int; 8392108Sphk size_t i, j; 8492108Sphk int found = 0; 8592108Sphk 8692108Sphk if (acl == NULL || entry_d == NULL) { 8792108Sphk errno = EINVAL; 8892108Sphk return (-1); 8992108Sphk } 9092108Sphk 9192108Sphk if (_entry_brand(entry_d) != _acl_brand(acl)) { 9292108Sphk errno = EINVAL; 9392108Sphk return (-1); 9492108Sphk } 9592108Sphk 9692108Sphk if ((acl->ats_acl.acl_cnt < 1) || 9792108Sphk (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { 9892108Sphk errno = EINVAL; 9992108Sphk return (-1); 10092108Sphk } 10192108Sphk 10292108Sphk /* Use a local copy to prevent deletion of more than this entry */ 10392108Sphk entry_int = *entry_d; 10492108Sphk 10592108Sphk for (i = 0; i < acl->ats_acl.acl_cnt;) { 10692108Sphk if (_entry_matches(&(acl->ats_acl.acl_entry[i]), &entry_int)) { 10792108Sphk /* ...shift the remaining entries... */ 10892108Sphk for (j = i; j < acl->ats_acl.acl_cnt - 1; ++j) 10992108Sphk acl->ats_acl.acl_entry[j] = 11092108Sphk acl->ats_acl.acl_entry[j+1]; 11192108Sphk /* ...drop the count and zero the unused entry... */ 11292108Sphk acl->ats_acl.acl_cnt--; 11392108Sphk bzero(&acl->ats_acl.acl_entry[j], 11492108Sphk sizeof(struct acl_entry)); 11592108Sphk acl->ats_cur_entry = 0; 11692108Sphk 11792108Sphk /* Continue with the loop to remove all matching entries. */ 11892108Sphk found = 1; 11992108Sphk } else 12092108Sphk i++; 12192108Sphk } 12292108Sphk 12392108Sphk if (found) 12492108Sphk return (0); 12592108Sphk 12692108Sphk errno = EINVAL; 12792108Sphk return (-1); 12892108Sphk} 12992108Sphk 13092108Sphkint 13192108Sphkacl_delete_entry_np(acl_t acl, int offset) 13292108Sphk{ 13392108Sphk struct acl *acl_int; 13492108Sphk size_t i; 13592108Sphk 13692108Sphk if (acl == NULL) { 13792108Sphk errno = EINVAL; 13892108Sphk return (-1); 13992108Sphk } 14092108Sphk 14192108Sphk acl_int = &acl->ats_acl; 14292108Sphk 14392108Sphk if (offset < 0 || (size_t)offset >= acl_int->acl_cnt) { 14492108Sphk errno = EINVAL; 14592108Sphk return (-1); 14692108Sphk } 14792108Sphk 14892108Sphk if ((acl->ats_acl.acl_cnt < 1) || 14992108Sphk (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) { 15092108Sphk errno = EINVAL; 15192108Sphk return (-1); 15292108Sphk } 15392108Sphk 15492108Sphk /* ...shift the remaining entries... */ 15592108Sphk for (i = offset; i < acl->ats_acl.acl_cnt - 1; ++i) 15692108Sphk acl->ats_acl.acl_entry[i] = 15792108Sphk acl->ats_acl.acl_entry[i+1]; 15892108Sphk /* ...drop the count and zero the unused entry... */ 15992108Sphk acl->ats_acl.acl_cnt--; 16092108Sphk bzero(&acl->ats_acl.acl_entry[i], 16192108Sphk sizeof(struct acl_entry)); 16292108Sphk acl->ats_cur_entry = 0; 16392108Sphk 16492108Sphk return (0); 16592108Sphk} 16692108Sphk