xref: /freebsd/lib/libc/posix1e/acl_equiv_mode_np.c (revision d81d5b2f2c9cda96ad960aac3313b89b2769323e)
1*d81d5b2fSGleb Popov /*-
2*d81d5b2fSGleb Popov  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*d81d5b2fSGleb Popov  *
4*d81d5b2fSGleb Popov  * Copyright (c) 2021 Gleb Popov
5*d81d5b2fSGleb Popov  * All rights reserved.
6*d81d5b2fSGleb Popov  *
7*d81d5b2fSGleb Popov  * Redistribution and use in source and binary forms, with or without
8*d81d5b2fSGleb Popov  * modification, are permitted provided that the following conditions
9*d81d5b2fSGleb Popov  * are met:
10*d81d5b2fSGleb Popov  * 1. Redistributions of source code must retain the above copyright
11*d81d5b2fSGleb Popov  *    notice, this list of conditions and the following disclaimer.
12*d81d5b2fSGleb Popov  * 2. Redistributions in binary form must reproduce the above copyright
13*d81d5b2fSGleb Popov  *    notice, this list of conditions and the following disclaimer in the
14*d81d5b2fSGleb Popov  *    documentation and/or other materials provided with the distribution.
15*d81d5b2fSGleb Popov  *
16*d81d5b2fSGleb Popov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*d81d5b2fSGleb Popov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*d81d5b2fSGleb Popov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*d81d5b2fSGleb Popov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*d81d5b2fSGleb Popov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*d81d5b2fSGleb Popov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*d81d5b2fSGleb Popov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*d81d5b2fSGleb Popov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*d81d5b2fSGleb Popov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*d81d5b2fSGleb Popov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*d81d5b2fSGleb Popov  * SUCH DAMAGE.
27*d81d5b2fSGleb Popov  */
28*d81d5b2fSGleb Popov /*
29*d81d5b2fSGleb Popov  * acl_equiv_mode_np: Check if an ACL can be represented as a mode_t.
30*d81d5b2fSGleb Popov  */
31*d81d5b2fSGleb Popov 
32*d81d5b2fSGleb Popov #include <sys/cdefs.h>
33*d81d5b2fSGleb Popov __FBSDID("$FreeBSD$");
34*d81d5b2fSGleb Popov 
35*d81d5b2fSGleb Popov #include <sys/types.h>
36*d81d5b2fSGleb Popov #include <sys/param.h>
37*d81d5b2fSGleb Popov #include <sys/errno.h>
38*d81d5b2fSGleb Popov #include <sys/stat.h>
39*d81d5b2fSGleb Popov #include <sys/acl.h>
40*d81d5b2fSGleb Popov 
41*d81d5b2fSGleb Popov #include "acl_support.h"
42*d81d5b2fSGleb Popov 
43*d81d5b2fSGleb Popov int
44*d81d5b2fSGleb Popov acl_equiv_mode_np(acl_t acl, mode_t *mode_p)
45*d81d5b2fSGleb Popov {
46*d81d5b2fSGleb Popov 	mode_t ret_mode = 0;
47*d81d5b2fSGleb Popov 
48*d81d5b2fSGleb Popov 	if (acl == NULL) {
49*d81d5b2fSGleb Popov 		errno = EINVAL;
50*d81d5b2fSGleb Popov 		return (-1);
51*d81d5b2fSGleb Popov 	}
52*d81d5b2fSGleb Popov 
53*d81d5b2fSGleb Popov 	/* Linux returns 0 for ACL returned by acl_init() */
54*d81d5b2fSGleb Popov 	if (_acl_brand(acl) == ACL_BRAND_UNKNOWN && acl->ats_acl.acl_cnt == 0)
55*d81d5b2fSGleb Popov 		return (0);
56*d81d5b2fSGleb Popov 
57*d81d5b2fSGleb Popov 	// TODO: Do we want to handle ACL_BRAND_NFS4 in this function? */
58*d81d5b2fSGleb Popov 	if (_acl_brand(acl) != ACL_BRAND_POSIX)
59*d81d5b2fSGleb Popov 		return (1);
60*d81d5b2fSGleb Popov 
61*d81d5b2fSGleb Popov 	for (int cur_entry = 0; cur_entry < acl->ats_acl.acl_cnt; cur_entry++) {
62*d81d5b2fSGleb Popov 		acl_entry_t entry = &acl->ats_acl.acl_entry[cur_entry];
63*d81d5b2fSGleb Popov 
64*d81d5b2fSGleb Popov 		if ((entry->ae_perm & ACL_PERM_BITS) != entry->ae_perm)
65*d81d5b2fSGleb Popov 			return (1);
66*d81d5b2fSGleb Popov 
67*d81d5b2fSGleb Popov 		switch (entry->ae_tag) {
68*d81d5b2fSGleb Popov 		case ACL_USER_OBJ:
69*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_READ)
70*d81d5b2fSGleb Popov 				ret_mode |= S_IRUSR;
71*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_WRITE)
72*d81d5b2fSGleb Popov 				ret_mode |= S_IWUSR;
73*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_EXECUTE)
74*d81d5b2fSGleb Popov 				ret_mode |= S_IXUSR;
75*d81d5b2fSGleb Popov 			break;
76*d81d5b2fSGleb Popov 		case ACL_GROUP_OBJ:
77*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_READ)
78*d81d5b2fSGleb Popov 				ret_mode |= S_IRGRP;
79*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_WRITE)
80*d81d5b2fSGleb Popov 				ret_mode |= S_IWGRP;
81*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_EXECUTE)
82*d81d5b2fSGleb Popov 				ret_mode |= S_IXGRP;
83*d81d5b2fSGleb Popov 			break;
84*d81d5b2fSGleb Popov 		case ACL_OTHER:
85*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_READ)
86*d81d5b2fSGleb Popov 				ret_mode |= S_IROTH;
87*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_WRITE)
88*d81d5b2fSGleb Popov 				ret_mode |= S_IWOTH;
89*d81d5b2fSGleb Popov 			if (entry->ae_perm & ACL_EXECUTE)
90*d81d5b2fSGleb Popov 				ret_mode |= S_IXOTH;
91*d81d5b2fSGleb Popov 			break;
92*d81d5b2fSGleb Popov 		default:
93*d81d5b2fSGleb Popov 			return (1);
94*d81d5b2fSGleb Popov 		}
95*d81d5b2fSGleb Popov 	}
96*d81d5b2fSGleb Popov 
97*d81d5b2fSGleb Popov 	if (mode_p != NULL)
98*d81d5b2fSGleb Popov 		*mode_p = ret_mode;
99*d81d5b2fSGleb Popov 
100*d81d5b2fSGleb Popov 	return (0);
101*d81d5b2fSGleb Popov }
102