xref: /freebsd/lib/libc/posix1e/acl_delete_entry.c (revision d915a14ef094c8dfc1a5aee70e135abfec01d0f1)
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