xref: /netbsd-src/lib/libc/posix1e/acl_get.c (revision 9aa2a9c323eb12a08584c70d6ea91d316703d3fe)
1*9aa2a9c3Schristos /*-
2*9aa2a9c3Schristos  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*9aa2a9c3Schristos  *
4*9aa2a9c3Schristos  * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
5*9aa2a9c3Schristos  * All rights reserved.
6*9aa2a9c3Schristos  *
7*9aa2a9c3Schristos  * This software was developed by Robert Watson for the TrustedBSD Project.
8*9aa2a9c3Schristos  *
9*9aa2a9c3Schristos  * Redistribution and use in source and binary forms, with or without
10*9aa2a9c3Schristos  * modification, are permitted provided that the following conditions
11*9aa2a9c3Schristos  * are met:
12*9aa2a9c3Schristos  * 1. Redistributions of source code must retain the above copyright
13*9aa2a9c3Schristos  *    notice, this list of conditions and the following disclaimer.
14*9aa2a9c3Schristos  * 2. Redistributions in binary form must reproduce the above copyright
15*9aa2a9c3Schristos  *    notice, this list of conditions and the following disclaimer in the
16*9aa2a9c3Schristos  *    documentation and/or other materials provided with the distribution.
17*9aa2a9c3Schristos  *
18*9aa2a9c3Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19*9aa2a9c3Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*9aa2a9c3Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*9aa2a9c3Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22*9aa2a9c3Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23*9aa2a9c3Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24*9aa2a9c3Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25*9aa2a9c3Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26*9aa2a9c3Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27*9aa2a9c3Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*9aa2a9c3Schristos  * SUCH DAMAGE.
29*9aa2a9c3Schristos  */
30*9aa2a9c3Schristos /*
31*9aa2a9c3Schristos  * acl_get_fd - syscall wrapper for retrieving access ACL by fd
32*9aa2a9c3Schristos  * acl_get_fd_np - syscall wrapper for retrieving ACL by fd (non-POSIX)
33*9aa2a9c3Schristos  * acl_get_file - syscall wrapper for retrieving ACL by filename
34*9aa2a9c3Schristos  * acl_get_link_np - syscall wrapper for retrieving ACL by filename (NOFOLLOW)
35*9aa2a9c3Schristos  *                   (non-POSIX)
36*9aa2a9c3Schristos  * acl_get_perm_np() checks if a permission is in the specified
37*9aa2a9c3Schristos  *                   permset (non-POSIX)
38*9aa2a9c3Schristos  * acl_get_permset() returns the permission set in the ACL entry
39*9aa2a9c3Schristos  * acl_get_qualifier() retrieves the qualifier of the tag from the ACL entry
40*9aa2a9c3Schristos  * acl_get_tag_type() returns the tag type for the ACL entry entry_d
41*9aa2a9c3Schristos  */
42*9aa2a9c3Schristos 
43*9aa2a9c3Schristos #include <sys/cdefs.h>
44*9aa2a9c3Schristos #if 0
45*9aa2a9c3Schristos __FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_get.c 326193 2017-11-25 17:12:48Z pfg $");
46*9aa2a9c3Schristos #else
47*9aa2a9c3Schristos __RCSID("$NetBSD: acl_get.c,v 1.1 2020/05/16 18:31:47 christos Exp $");
48*9aa2a9c3Schristos #endif
49*9aa2a9c3Schristos 
50*9aa2a9c3Schristos #include "namespace.h"
51*9aa2a9c3Schristos #include <sys/types.h>
52*9aa2a9c3Schristos #include <sys/acl.h>
53*9aa2a9c3Schristos 
54*9aa2a9c3Schristos #include <errno.h>
55*9aa2a9c3Schristos #include <stdio.h>
56*9aa2a9c3Schristos #include <stdlib.h>
57*9aa2a9c3Schristos #include <string.h>
58*9aa2a9c3Schristos #include <unistd.h>
59*9aa2a9c3Schristos 
60*9aa2a9c3Schristos #include "acl_support.h"
61*9aa2a9c3Schristos 
62*9aa2a9c3Schristos acl_t
acl_get_file(const char * path_p,acl_type_t type)63*9aa2a9c3Schristos acl_get_file(const char *path_p, acl_type_t type)
64*9aa2a9c3Schristos {
65*9aa2a9c3Schristos 	acl_t	aclp;
66*9aa2a9c3Schristos 	int	error;
67*9aa2a9c3Schristos 
68*9aa2a9c3Schristos 	aclp = acl_init(ACL_MAX_ENTRIES);
69*9aa2a9c3Schristos 	if (aclp == NULL)
70*9aa2a9c3Schristos 		return (NULL);
71*9aa2a9c3Schristos 
72*9aa2a9c3Schristos 	type = _acl_type_unold(type);
73*9aa2a9c3Schristos 	error = __acl_get_file(path_p, type, &aclp->ats_acl);
74*9aa2a9c3Schristos 	if (error) {
75*9aa2a9c3Schristos 		acl_free(aclp);
76*9aa2a9c3Schristos 		return (NULL);
77*9aa2a9c3Schristos 	}
78*9aa2a9c3Schristos 
79*9aa2a9c3Schristos 	aclp->ats_acl.acl_maxcnt = ACL_MAX_ENTRIES;
80*9aa2a9c3Schristos 	_acl_brand_from_type(aclp, type);
81*9aa2a9c3Schristos 
82*9aa2a9c3Schristos 	return (aclp);
83*9aa2a9c3Schristos }
84*9aa2a9c3Schristos 
85*9aa2a9c3Schristos acl_t
acl_get_link_np(const char * path_p,acl_type_t type)86*9aa2a9c3Schristos acl_get_link_np(const char *path_p, acl_type_t type)
87*9aa2a9c3Schristos {
88*9aa2a9c3Schristos 	acl_t	aclp;
89*9aa2a9c3Schristos 	int	error;
90*9aa2a9c3Schristos 
91*9aa2a9c3Schristos 	aclp = acl_init(ACL_MAX_ENTRIES);
92*9aa2a9c3Schristos 	if (aclp == NULL)
93*9aa2a9c3Schristos 		return (NULL);
94*9aa2a9c3Schristos 
95*9aa2a9c3Schristos 	type = _acl_type_unold(type);
96*9aa2a9c3Schristos 	error = __acl_get_link(path_p, type, &aclp->ats_acl);
97*9aa2a9c3Schristos 	if (error) {
98*9aa2a9c3Schristos 		acl_free(aclp);
99*9aa2a9c3Schristos 		return (NULL);
100*9aa2a9c3Schristos 	}
101*9aa2a9c3Schristos 
102*9aa2a9c3Schristos 	aclp->ats_acl.acl_maxcnt = ACL_MAX_ENTRIES;
103*9aa2a9c3Schristos 	_acl_brand_from_type(aclp, type);
104*9aa2a9c3Schristos 
105*9aa2a9c3Schristos 	return (aclp);
106*9aa2a9c3Schristos }
107*9aa2a9c3Schristos 
108*9aa2a9c3Schristos acl_t
acl_get_fd(int fd)109*9aa2a9c3Schristos acl_get_fd(int fd)
110*9aa2a9c3Schristos {
111*9aa2a9c3Schristos 	if (fpathconf(fd, _PC_ACL_NFS4) == 1)
112*9aa2a9c3Schristos 		return (acl_get_fd_np(fd, ACL_TYPE_NFS4));
113*9aa2a9c3Schristos 
114*9aa2a9c3Schristos 	return (acl_get_fd_np(fd, ACL_TYPE_ACCESS));
115*9aa2a9c3Schristos }
116*9aa2a9c3Schristos 
117*9aa2a9c3Schristos acl_t
acl_get_fd_np(int fd,acl_type_t type)118*9aa2a9c3Schristos acl_get_fd_np(int fd, acl_type_t type)
119*9aa2a9c3Schristos {
120*9aa2a9c3Schristos 	acl_t	aclp;
121*9aa2a9c3Schristos 	int	error;
122*9aa2a9c3Schristos 
123*9aa2a9c3Schristos 	aclp = acl_init(ACL_MAX_ENTRIES);
124*9aa2a9c3Schristos 	if (aclp == NULL)
125*9aa2a9c3Schristos 		return (NULL);
126*9aa2a9c3Schristos 
127*9aa2a9c3Schristos 	type = _acl_type_unold(type);
128*9aa2a9c3Schristos 	error = __acl_get_fd(fd, type, &aclp->ats_acl);
129*9aa2a9c3Schristos 	if (error) {
130*9aa2a9c3Schristos 		acl_free(aclp);
131*9aa2a9c3Schristos 		return (NULL);
132*9aa2a9c3Schristos 	}
133*9aa2a9c3Schristos 
134*9aa2a9c3Schristos 	aclp->ats_acl.acl_maxcnt = ACL_MAX_ENTRIES;
135*9aa2a9c3Schristos 	_acl_brand_from_type(aclp, type);
136*9aa2a9c3Schristos 
137*9aa2a9c3Schristos 	return (aclp);
138*9aa2a9c3Schristos }
139*9aa2a9c3Schristos 
140*9aa2a9c3Schristos /*
141*9aa2a9c3Schristos  * acl_get_permset() (23.4.17): return via permset_p a descriptor to
142*9aa2a9c3Schristos  * the permission set in the ACL entry entry_d.
143*9aa2a9c3Schristos  */
144*9aa2a9c3Schristos int
acl_get_permset(acl_entry_t entry_d,acl_permset_t * permset_p)145*9aa2a9c3Schristos acl_get_permset(acl_entry_t entry_d, acl_permset_t *permset_p)
146*9aa2a9c3Schristos {
147*9aa2a9c3Schristos 
148*9aa2a9c3Schristos 	if (entry_d == NULL || permset_p == NULL) {
149*9aa2a9c3Schristos 		errno = EINVAL;
150*9aa2a9c3Schristos 		return (-1);
151*9aa2a9c3Schristos 	}
152*9aa2a9c3Schristos 
153*9aa2a9c3Schristos 	*permset_p = &entry_d->ae_perm;
154*9aa2a9c3Schristos 
155*9aa2a9c3Schristos 	return (0);
156*9aa2a9c3Schristos }
157*9aa2a9c3Schristos 
158*9aa2a9c3Schristos /*
159*9aa2a9c3Schristos  * acl_get_qualifier() (23.4.18): retrieve the qualifier of the tag
160*9aa2a9c3Schristos  * for the ACL entry entry_d.
161*9aa2a9c3Schristos  */
162*9aa2a9c3Schristos void *
acl_get_qualifier(acl_entry_t entry_d)163*9aa2a9c3Schristos acl_get_qualifier(acl_entry_t entry_d)
164*9aa2a9c3Schristos {
165*9aa2a9c3Schristos 	uid_t *retval;
166*9aa2a9c3Schristos 
167*9aa2a9c3Schristos 	if (entry_d == NULL) {
168*9aa2a9c3Schristos 		errno = EINVAL;
169*9aa2a9c3Schristos 		return (NULL);
170*9aa2a9c3Schristos 	}
171*9aa2a9c3Schristos 
172*9aa2a9c3Schristos 	switch(entry_d->ae_tag) {
173*9aa2a9c3Schristos 	case ACL_USER:
174*9aa2a9c3Schristos 	case ACL_GROUP:
175*9aa2a9c3Schristos 		retval = malloc(sizeof(uid_t));
176*9aa2a9c3Schristos 		if (retval == NULL)
177*9aa2a9c3Schristos 			return (NULL);
178*9aa2a9c3Schristos 		*retval = entry_d->ae_id;
179*9aa2a9c3Schristos 		return (retval);
180*9aa2a9c3Schristos 	}
181*9aa2a9c3Schristos 
182*9aa2a9c3Schristos 	errno = EINVAL;
183*9aa2a9c3Schristos 	return (NULL);
184*9aa2a9c3Schristos }
185*9aa2a9c3Schristos 
186*9aa2a9c3Schristos /*
187*9aa2a9c3Schristos  * acl_get_tag_type() (23.4.19): return the tag type for the ACL
188*9aa2a9c3Schristos  * entry entry_p.
189*9aa2a9c3Schristos  */
190*9aa2a9c3Schristos int
acl_get_tag_type(acl_entry_t entry_d,acl_tag_t * tag_type_p)191*9aa2a9c3Schristos acl_get_tag_type(acl_entry_t entry_d, acl_tag_t *tag_type_p)
192*9aa2a9c3Schristos {
193*9aa2a9c3Schristos 
194*9aa2a9c3Schristos 	if (entry_d == NULL || tag_type_p == NULL) {
195*9aa2a9c3Schristos 		errno = EINVAL;
196*9aa2a9c3Schristos 		return (-1);
197*9aa2a9c3Schristos 	}
198*9aa2a9c3Schristos 
199*9aa2a9c3Schristos 	*tag_type_p = entry_d->ae_tag;
200*9aa2a9c3Schristos 
201*9aa2a9c3Schristos 	return (0);
202*9aa2a9c3Schristos }
203*9aa2a9c3Schristos 
204*9aa2a9c3Schristos int
acl_get_entry_type_np(acl_entry_t entry_d,acl_entry_type_t * entry_type_p)205*9aa2a9c3Schristos acl_get_entry_type_np(acl_entry_t entry_d, acl_entry_type_t *entry_type_p)
206*9aa2a9c3Schristos {
207*9aa2a9c3Schristos 
208*9aa2a9c3Schristos 	if (entry_d == NULL || entry_type_p == NULL) {
209*9aa2a9c3Schristos 		errno = EINVAL;
210*9aa2a9c3Schristos 		return (-1);
211*9aa2a9c3Schristos 	}
212*9aa2a9c3Schristos 
213*9aa2a9c3Schristos 	if (!_entry_brand_may_be(entry_d, ACL_BRAND_NFS4)) {
214*9aa2a9c3Schristos 		errno = EINVAL;
215*9aa2a9c3Schristos 		return (-1);
216*9aa2a9c3Schristos 	}
217*9aa2a9c3Schristos 
218*9aa2a9c3Schristos 	*entry_type_p = entry_d->ae_entry_type;
219*9aa2a9c3Schristos 
220*9aa2a9c3Schristos 	return (0);
221*9aa2a9c3Schristos }
222