1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2021 Robert N M Watson, Gleb Popov
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 /*
29 * acl_from_mode_np: Create an ACL from a mode_t.
30 */
31
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/acl.h>
35 #include <sys/stat.h>
36
37 /*
38 * return an ACL corresponding to the permissions
39 * contained in mode_t
40 */
41 acl_t
acl_from_mode_np(const mode_t mode)42 acl_from_mode_np(const mode_t mode)
43 {
44 acl_t acl;
45 acl_entry_t entry;
46 acl_permset_t perms;
47
48 /* create the ACL */
49 acl = acl_init(3);
50 /* here and below, the only possible reason to fail is ENOMEM, so
51 * no need to set errno again
52 */
53 if (acl == NULL)
54 return (NULL);
55
56 /* First entry: ACL_USER_OBJ */
57 if (acl_create_entry(&acl, &entry) == -1)
58 return (NULL);
59 /* TODO: need to handle error there and below? */
60 acl_set_tag_type(entry, ACL_USER_OBJ);
61
62 acl_get_permset(entry, &perms);
63 acl_clear_perms(perms);
64
65 /* calculate user mode */
66 if (mode & S_IRUSR)
67 acl_add_perm(perms, ACL_READ);
68 if (mode & S_IWUSR)
69 acl_add_perm(perms, ACL_WRITE);
70 if (mode & S_IXUSR)
71 acl_add_perm(perms, ACL_EXECUTE);
72
73 acl_set_permset(entry, perms);
74
75 /* Second entry: ACL_GROUP_OBJ */
76 if (acl_create_entry(&acl, &entry) == -1)
77 return (NULL);
78 acl_set_tag_type(entry, ACL_GROUP_OBJ);
79
80 acl_get_permset(entry, &perms);
81 acl_clear_perms(perms);
82
83 /* calculate group mode */
84 if (mode & S_IRGRP)
85 acl_add_perm(perms, ACL_READ);
86 if (mode & S_IWGRP)
87 acl_add_perm(perms, ACL_WRITE);
88 if (mode & S_IXGRP)
89 acl_add_perm(perms, ACL_EXECUTE);
90
91 acl_set_permset(entry, perms);
92
93 /* Third entry: ACL_OTHER */
94 if (acl_create_entry(&acl, &entry) == -1)
95 return (NULL);
96 acl_set_tag_type(entry, ACL_OTHER);
97
98 acl_get_permset(entry, &perms);
99 acl_clear_perms(perms);
100
101 /* calculate other mode */
102 if (mode & S_IROTH)
103 acl_add_perm(perms, ACL_READ);
104 if (mode & S_IWOTH)
105 acl_add_perm(perms, ACL_WRITE);
106 if (mode & S_IXOTH)
107 acl_add_perm(perms, ACL_EXECUTE);
108
109 acl_set_permset(entry, perms);
110
111 return (acl);
112 }
113