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