xref: /netbsd-src/lib/libc/posix1e/acl_entry.c (revision 9aa2a9c323eb12a08584c70d6ea91d316703d3fe)
1*9aa2a9c3Schristos /*-
2*9aa2a9c3Schristos  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*9aa2a9c3Schristos  *
4*9aa2a9c3Schristos  * Copyright (c) 2001-2002 Chris D. Faulhaber
5*9aa2a9c3Schristos  * All rights reserved.
6*9aa2a9c3Schristos  *
7*9aa2a9c3Schristos  * Redistribution and use in source and binary forms, with or without
8*9aa2a9c3Schristos  * modification, are permitted provided that the following conditions
9*9aa2a9c3Schristos  * are met:
10*9aa2a9c3Schristos  * 1. Redistributions of source code must retain the above copyright
11*9aa2a9c3Schristos  *    notice, this list of conditions and the following disclaimer.
12*9aa2a9c3Schristos  * 2. Redistributions in binary form must reproduce the above copyright
13*9aa2a9c3Schristos  *    notice, this list of conditions and the following disclaimer in the
14*9aa2a9c3Schristos  *    documentation and/or other materials provided with the distribution.
15*9aa2a9c3Schristos  *
16*9aa2a9c3Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*9aa2a9c3Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*9aa2a9c3Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*9aa2a9c3Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*9aa2a9c3Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*9aa2a9c3Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*9aa2a9c3Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*9aa2a9c3Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*9aa2a9c3Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*9aa2a9c3Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*9aa2a9c3Schristos  * SUCH DAMAGE.
27*9aa2a9c3Schristos  */
28*9aa2a9c3Schristos 
29*9aa2a9c3Schristos #include <sys/cdefs.h>
30*9aa2a9c3Schristos #if 0
31*9aa2a9c3Schristos __FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_entry.c 326193 2017-11-25 17:12:48Z pfg $");
32*9aa2a9c3Schristos #else
33*9aa2a9c3Schristos __RCSID("$NetBSD: acl_entry.c,v 1.1 2020/05/16 18:31:47 christos Exp $");
34*9aa2a9c3Schristos #endif
35*9aa2a9c3Schristos 
36*9aa2a9c3Schristos #include "namespace.h"
37*9aa2a9c3Schristos #include <sys/types.h>
38*9aa2a9c3Schristos #include <sys/acl.h>
39*9aa2a9c3Schristos 
40*9aa2a9c3Schristos #include <errno.h>
41*9aa2a9c3Schristos #include <stdlib.h>
42*9aa2a9c3Schristos 
43*9aa2a9c3Schristos /*
44*9aa2a9c3Schristos  * acl_create_entry() (23.4.7): create a new ACL entry in the ACL pointed
45*9aa2a9c3Schristos  * to by acl_p.
46*9aa2a9c3Schristos  */
47*9aa2a9c3Schristos int
acl_create_entry(acl_t * acl_p,acl_entry_t * entry_p)48*9aa2a9c3Schristos acl_create_entry(acl_t *acl_p, acl_entry_t *entry_p)
49*9aa2a9c3Schristos {
50*9aa2a9c3Schristos 	struct acl *acl_int;
51*9aa2a9c3Schristos 
52*9aa2a9c3Schristos 	if (acl_p == NULL) {
53*9aa2a9c3Schristos 		errno = EINVAL;
54*9aa2a9c3Schristos 		return (-1);
55*9aa2a9c3Schristos 	}
56*9aa2a9c3Schristos 
57*9aa2a9c3Schristos 	acl_int = &(*acl_p)->ats_acl;
58*9aa2a9c3Schristos 
59*9aa2a9c3Schristos 	/*
60*9aa2a9c3Schristos 	 * +1, because we are checking if there is space left for one more
61*9aa2a9c3Schristos 	 * entry.
62*9aa2a9c3Schristos 	 */
63*9aa2a9c3Schristos 	if (acl_int->acl_cnt + 1 >= ACL_MAX_ENTRIES) {
64*9aa2a9c3Schristos 		errno = EINVAL;
65*9aa2a9c3Schristos 		return (-1);
66*9aa2a9c3Schristos 	}
67*9aa2a9c3Schristos 
68*9aa2a9c3Schristos 	*entry_p = &acl_int->acl_entry[acl_int->acl_cnt++];
69*9aa2a9c3Schristos 
70*9aa2a9c3Schristos 	(**entry_p).ae_tag  = ACL_UNDEFINED_TAG;
71*9aa2a9c3Schristos 	(**entry_p).ae_id   = ACL_UNDEFINED_ID;
72*9aa2a9c3Schristos 	(**entry_p).ae_perm = ACL_PERM_NONE;
73*9aa2a9c3Schristos 	(**entry_p).ae_entry_type = 0;
74*9aa2a9c3Schristos 	(**entry_p).ae_flags = 0;
75*9aa2a9c3Schristos 
76*9aa2a9c3Schristos 	(*acl_p)->ats_cur_entry = 0;
77*9aa2a9c3Schristos 
78*9aa2a9c3Schristos 	return (0);
79*9aa2a9c3Schristos }
80*9aa2a9c3Schristos 
81*9aa2a9c3Schristos int
acl_create_entry_np(acl_t * acl_p,acl_entry_t * entry_p,int offset)82*9aa2a9c3Schristos acl_create_entry_np(acl_t *acl_p, acl_entry_t *entry_p, int offset)
83*9aa2a9c3Schristos {
84*9aa2a9c3Schristos 	int i;
85*9aa2a9c3Schristos 	struct acl *acl_int;
86*9aa2a9c3Schristos 
87*9aa2a9c3Schristos 	if (acl_p == NULL) {
88*9aa2a9c3Schristos 		errno = EINVAL;
89*9aa2a9c3Schristos 		return (-1);
90*9aa2a9c3Schristos 	}
91*9aa2a9c3Schristos 
92*9aa2a9c3Schristos 	acl_int = &(*acl_p)->ats_acl;
93*9aa2a9c3Schristos 
94*9aa2a9c3Schristos 	if (acl_int->acl_cnt + 1 >= ACL_MAX_ENTRIES) {
95*9aa2a9c3Schristos 		errno = EINVAL;
96*9aa2a9c3Schristos 		return (-1);
97*9aa2a9c3Schristos 	}
98*9aa2a9c3Schristos 
99*9aa2a9c3Schristos 	if (offset < 0 || (size_t)offset > acl_int->acl_cnt) {
100*9aa2a9c3Schristos 		errno = EINVAL;
101*9aa2a9c3Schristos 		return (-1);
102*9aa2a9c3Schristos 	}
103*9aa2a9c3Schristos 
104*9aa2a9c3Schristos 	/* Make room for the new entry. */
105*9aa2a9c3Schristos 	for (i = acl_int->acl_cnt; i > offset; i--)
106*9aa2a9c3Schristos 		acl_int->acl_entry[i] = acl_int->acl_entry[i - 1];
107*9aa2a9c3Schristos 
108*9aa2a9c3Schristos 	acl_int->acl_cnt++;
109*9aa2a9c3Schristos 
110*9aa2a9c3Schristos 	*entry_p = &acl_int->acl_entry[offset];
111*9aa2a9c3Schristos 
112*9aa2a9c3Schristos 	(**entry_p).ae_tag  = ACL_UNDEFINED_TAG;
113*9aa2a9c3Schristos 	(**entry_p).ae_id   = ACL_UNDEFINED_ID;
114*9aa2a9c3Schristos 	(**entry_p).ae_perm = ACL_PERM_NONE;
115*9aa2a9c3Schristos 	(**entry_p).ae_entry_type = 0;
116*9aa2a9c3Schristos 	(**entry_p).ae_flags= 0;
117*9aa2a9c3Schristos 
118*9aa2a9c3Schristos 	(*acl_p)->ats_cur_entry = 0;
119*9aa2a9c3Schristos 
120*9aa2a9c3Schristos 	return (0);
121*9aa2a9c3Schristos }
122*9aa2a9c3Schristos 
123*9aa2a9c3Schristos /*
124*9aa2a9c3Schristos  * acl_get_entry() (23.4.14): returns an ACL entry from an ACL
125*9aa2a9c3Schristos  * indicated by entry_id.
126*9aa2a9c3Schristos  */
127*9aa2a9c3Schristos int
acl_get_entry(acl_t acl,int entry_id,acl_entry_t * entry_p)128*9aa2a9c3Schristos acl_get_entry(acl_t acl, int entry_id, acl_entry_t *entry_p)
129*9aa2a9c3Schristos {
130*9aa2a9c3Schristos 	struct acl *acl_int;
131*9aa2a9c3Schristos 
132*9aa2a9c3Schristos 	if (acl == NULL) {
133*9aa2a9c3Schristos 		errno = EINVAL;
134*9aa2a9c3Schristos 		return (-1);
135*9aa2a9c3Schristos 	}
136*9aa2a9c3Schristos 	acl_int = &acl->ats_acl;
137*9aa2a9c3Schristos 
138*9aa2a9c3Schristos 	switch(entry_id) {
139*9aa2a9c3Schristos 	case ACL_FIRST_ENTRY:
140*9aa2a9c3Schristos 		acl->ats_cur_entry = 0;
141*9aa2a9c3Schristos 		/* FALLTHROUGH */
142*9aa2a9c3Schristos 	case ACL_NEXT_ENTRY:
143*9aa2a9c3Schristos 		if (acl->ats_cur_entry >= acl->ats_acl.acl_cnt)
144*9aa2a9c3Schristos 			return 0;
145*9aa2a9c3Schristos 		*entry_p = &acl_int->acl_entry[acl->ats_cur_entry++];
146*9aa2a9c3Schristos 		return (1);
147*9aa2a9c3Schristos 	}
148*9aa2a9c3Schristos 
149*9aa2a9c3Schristos 	errno = EINVAL;
150*9aa2a9c3Schristos 	return (-1);
151*9aa2a9c3Schristos }
152