1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson for the TrustedBSD Project.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30 /*
31 * acl_set_file -- set a file/directory ACL by name
32 */
33
34 #include <sys/cdefs.h>
35 #include <sys/types.h>
36 #include "namespace.h"
37 #include <sys/acl.h>
38 #include "un-namespace.h"
39
40 #include <errno.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44
45 #include "acl_support.h"
46
47 /*
48 * For POSIX.1e-semantic ACLs, do a presort so the kernel doesn't have to
49 * (the POSIX.1e semantic code will reject unsorted ACL submission). If it's
50 * not a semantic that the library knows about, just submit it flat and
51 * assume the caller knows what they're up to.
52 */
53 int
acl_set_file(const char * path_p,acl_type_t type,acl_t acl)54 acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
55 {
56
57 if (acl == NULL || path_p == NULL) {
58 errno = EINVAL;
59 return (-1);
60 }
61 type = _acl_type_unold(type);
62 if (_acl_type_not_valid_for_acl(acl, type)) {
63 errno = EINVAL;
64 return (-1);
65 }
66 if (_posix1e_acl(acl, type))
67 _posix1e_acl_sort(acl);
68
69 acl->ats_cur_entry = 0;
70
71 return (__acl_set_file(path_p, type, &acl->ats_acl));
72 }
73
74 int
acl_set_link_np(const char * path_p,acl_type_t type,acl_t acl)75 acl_set_link_np(const char *path_p, acl_type_t type, acl_t acl)
76 {
77
78 if (acl == NULL || path_p == NULL) {
79 errno = EINVAL;
80 return (-1);
81 }
82 type = _acl_type_unold(type);
83 if (_acl_type_not_valid_for_acl(acl, type)) {
84 errno = EINVAL;
85 return (-1);
86 }
87 if (_posix1e_acl(acl, type))
88 _posix1e_acl_sort(acl);
89
90 acl->ats_cur_entry = 0;
91
92 return (__acl_set_link(path_p, type, &acl->ats_acl));
93 }
94
95 int
acl_set_fd(int fd,acl_t acl)96 acl_set_fd(int fd, acl_t acl)
97 {
98
99 if (fpathconf(fd, _PC_ACL_NFS4) == 1)
100 return (acl_set_fd_np(fd, acl, ACL_TYPE_NFS4));
101
102 return (acl_set_fd_np(fd, acl, ACL_TYPE_ACCESS));
103 }
104
105 int
acl_set_fd_np(int fd,acl_t acl,acl_type_t type)106 acl_set_fd_np(int fd, acl_t acl, acl_type_t type)
107 {
108
109 if (acl == NULL) {
110 errno = EINVAL;
111 return (-1);
112 }
113 type = _acl_type_unold(type);
114 if (_acl_type_not_valid_for_acl(acl, type)) {
115 errno = EINVAL;
116 return (-1);
117 }
118 if (_posix1e_acl(acl, type))
119 _posix1e_acl_sort(acl);
120
121 acl->ats_cur_entry = 0;
122
123 return (___acl_set_fd(fd, type, &acl->ats_acl));
124 }
125
126 /*
127 * acl_set_permset() (23.4.23): sets the permissions of ACL entry entry_d
128 * with the permissions in permset_d
129 */
130 int
acl_set_permset(acl_entry_t entry_d,acl_permset_t permset_d)131 acl_set_permset(acl_entry_t entry_d, acl_permset_t permset_d)
132 {
133
134 if (!entry_d) {
135 errno = EINVAL;
136 return (-1);
137 }
138
139 if ((*permset_d & ACL_POSIX1E_BITS) != *permset_d) {
140 if ((*permset_d & ACL_NFS4_PERM_BITS) != *permset_d) {
141 errno = EINVAL;
142 return (-1);
143 }
144 if (!_entry_brand_may_be(entry_d, ACL_BRAND_NFS4)) {
145 errno = EINVAL;
146 return (-1);
147 }
148 _entry_brand_as(entry_d, ACL_BRAND_NFS4);
149 }
150
151 entry_d->ae_perm = *permset_d;
152
153 return (0);
154 }
155
156 /*
157 * acl_set_qualifier() sets the qualifier (ae_id) of the tag for
158 * ACL entry entry_d to the value referred to by tag_qualifier_p
159 */
160 int
acl_set_qualifier(acl_entry_t entry_d,const void * tag_qualifier_p)161 acl_set_qualifier(acl_entry_t entry_d, const void *tag_qualifier_p)
162 {
163
164 if (!entry_d || !tag_qualifier_p) {
165 errno = EINVAL;
166 return (-1);
167 }
168 switch(entry_d->ae_tag) {
169 case ACL_USER:
170 case ACL_GROUP:
171 entry_d->ae_id = *(uid_t *)tag_qualifier_p;
172 break;
173 default:
174 errno = EINVAL;
175 return (-1);
176 }
177
178 return (0);
179 }
180
181 /*
182 * acl_set_tag_type() sets the tag type for ACL entry entry_d to the
183 * value of tag_type
184 */
185 int
acl_set_tag_type(acl_entry_t entry_d,acl_tag_t tag_type)186 acl_set_tag_type(acl_entry_t entry_d, acl_tag_t tag_type)
187 {
188
189 if (entry_d == NULL) {
190 errno = EINVAL;
191 return (-1);
192 }
193
194 switch(tag_type) {
195 case ACL_OTHER:
196 case ACL_MASK:
197 if (!_entry_brand_may_be(entry_d, ACL_BRAND_POSIX)) {
198 errno = EINVAL;
199 return (-1);
200 }
201 _entry_brand_as(entry_d, ACL_BRAND_POSIX);
202 break;
203 case ACL_EVERYONE:
204 if (!_entry_brand_may_be(entry_d, ACL_BRAND_NFS4)) {
205 errno = EINVAL;
206 return (-1);
207 }
208 _entry_brand_as(entry_d, ACL_BRAND_NFS4);
209 break;
210 }
211
212 switch(tag_type) {
213 case ACL_USER_OBJ:
214 case ACL_USER:
215 case ACL_GROUP_OBJ:
216 case ACL_GROUP:
217 case ACL_MASK:
218 case ACL_OTHER:
219 case ACL_EVERYONE:
220 entry_d->ae_tag = tag_type;
221 return (0);
222 }
223
224 errno = EINVAL;
225 return (-1);
226 }
227
228 int
acl_set_entry_type_np(acl_entry_t entry_d,acl_entry_type_t entry_type)229 acl_set_entry_type_np(acl_entry_t entry_d, acl_entry_type_t entry_type)
230 {
231
232 if (entry_d == NULL) {
233 errno = EINVAL;
234 return (-1);
235 }
236 if (!_entry_brand_may_be(entry_d, ACL_BRAND_NFS4)) {
237 errno = EINVAL;
238 return (-1);
239 }
240 _entry_brand_as(entry_d, ACL_BRAND_NFS4);
241
242 switch (entry_type) {
243 case ACL_ENTRY_TYPE_ALLOW:
244 case ACL_ENTRY_TYPE_DENY:
245 case ACL_ENTRY_TYPE_AUDIT:
246 case ACL_ENTRY_TYPE_ALARM:
247 entry_d->ae_entry_type = entry_type;
248 return (0);
249 }
250
251 errno = EINVAL;
252 return (-1);
253 }
254