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