xref: /freebsd/sys/contrib/openzfs/module/os/freebsd/spl/acl_common.c (revision 34f9f5680c9d5d5138e427ba3aeab0138cec3882)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * This file and its contents are supplied under the terms of the
4  * Common Development and Distribution License ("CDDL"), version 1.0.
5  * You may only use this file in accordance with the terms of version
6  * 1.0 of the CDDL.
7  *
8  * A full copy of the text of the CDDL should have accompanied this
9  * source.  A copy of the CDDL is also available via the Internet at
10  * https://opensource.org/license/CDDL-1.0.
11  */
12 /*
13  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
14  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
15  */
16 
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/avl.h>
20 #include <sys/misc.h>
21 #include <sys/kmem.h>
22 #include <sys/systm.h>
23 #include <sys/sysmacros.h>
24 #include <acl/acl_common.h>
25 #include <sys/debug.h>
26 
27 #define	ACE_POSIX_SUPPORTED_BITS (ACE_READ_DATA | \
28     ACE_WRITE_DATA | ACE_APPEND_DATA | ACE_EXECUTE | \
29     ACE_READ_ATTRIBUTES | ACE_READ_ACL | ACE_WRITE_ACL)
30 
31 
32 #define	ACL_SYNCHRONIZE_SET_DENY		0x0000001
33 #define	ACL_SYNCHRONIZE_SET_ALLOW		0x0000002
34 #define	ACL_SYNCHRONIZE_ERR_DENY		0x0000004
35 #define	ACL_SYNCHRONIZE_ERR_ALLOW		0x0000008
36 
37 #define	ACL_WRITE_OWNER_SET_DENY		0x0000010
38 #define	ACL_WRITE_OWNER_SET_ALLOW		0x0000020
39 #define	ACL_WRITE_OWNER_ERR_DENY		0x0000040
40 #define	ACL_WRITE_OWNER_ERR_ALLOW		0x0000080
41 
42 #define	ACL_DELETE_SET_DENY			0x0000100
43 #define	ACL_DELETE_SET_ALLOW			0x0000200
44 #define	ACL_DELETE_ERR_DENY			0x0000400
45 #define	ACL_DELETE_ERR_ALLOW			0x0000800
46 
47 #define	ACL_WRITE_ATTRS_OWNER_SET_DENY		0x0001000
48 #define	ACL_WRITE_ATTRS_OWNER_SET_ALLOW		0x0002000
49 #define	ACL_WRITE_ATTRS_OWNER_ERR_DENY		0x0004000
50 #define	ACL_WRITE_ATTRS_OWNER_ERR_ALLOW		0x0008000
51 
52 #define	ACL_WRITE_ATTRS_WRITER_SET_DENY		0x0010000
53 #define	ACL_WRITE_ATTRS_WRITER_SET_ALLOW	0x0020000
54 #define	ACL_WRITE_ATTRS_WRITER_ERR_DENY		0x0040000
55 #define	ACL_WRITE_ATTRS_WRITER_ERR_ALLOW	0x0080000
56 
57 #define	ACL_WRITE_NAMED_WRITER_SET_DENY		0x0100000
58 #define	ACL_WRITE_NAMED_WRITER_SET_ALLOW	0x0200000
59 #define	ACL_WRITE_NAMED_WRITER_ERR_DENY		0x0400000
60 #define	ACL_WRITE_NAMED_WRITER_ERR_ALLOW	0x0800000
61 
62 #define	ACL_READ_NAMED_READER_SET_DENY		0x1000000
63 #define	ACL_READ_NAMED_READER_SET_ALLOW		0x2000000
64 #define	ACL_READ_NAMED_READER_ERR_DENY		0x4000000
65 #define	ACL_READ_NAMED_READER_ERR_ALLOW		0x8000000
66 
67 
68 #define	ACE_VALID_MASK_BITS (\
69     ACE_READ_DATA | \
70     ACE_LIST_DIRECTORY | \
71     ACE_WRITE_DATA | \
72     ACE_ADD_FILE | \
73     ACE_APPEND_DATA | \
74     ACE_ADD_SUBDIRECTORY | \
75     ACE_READ_NAMED_ATTRS | \
76     ACE_WRITE_NAMED_ATTRS | \
77     ACE_EXECUTE | \
78     ACE_DELETE_CHILD | \
79     ACE_READ_ATTRIBUTES | \
80     ACE_WRITE_ATTRIBUTES | \
81     ACE_DELETE | \
82     ACE_READ_ACL | \
83     ACE_WRITE_ACL | \
84     ACE_WRITE_OWNER | \
85     ACE_SYNCHRONIZE)
86 
87 #define	ACE_MASK_UNDEFINED			0x80000000
88 
89 #define	ACE_VALID_FLAG_BITS (ACE_FILE_INHERIT_ACE | \
90     ACE_DIRECTORY_INHERIT_ACE | \
91     ACE_NO_PROPAGATE_INHERIT_ACE | ACE_INHERIT_ONLY_ACE | \
92     ACE_SUCCESSFUL_ACCESS_ACE_FLAG | ACE_FAILED_ACCESS_ACE_FLAG | \
93     ACE_IDENTIFIER_GROUP | ACE_OWNER | ACE_GROUP | ACE_EVERYONE)
94 
95 /*
96  * ACL conversion helpers
97  */
98 
99 typedef enum {
100 	ace_unused,
101 	ace_user_obj,
102 	ace_user,
103 	ace_group, /* includes GROUP and GROUP_OBJ */
104 	ace_other_obj
105 } ace_to_aent_state_t;
106 
107 typedef struct acevals {
108 	uid_t key;
109 	avl_node_t avl;
110 	uint32_t mask;
111 	uint32_t allowed;
112 	uint32_t denied;
113 	int aent_type;
114 } acevals_t;
115 
116 typedef struct ace_list {
117 	acevals_t user_obj;
118 	avl_tree_t user;
119 	int numusers;
120 	acevals_t group_obj;
121 	avl_tree_t group;
122 	int numgroups;
123 	acevals_t other_obj;
124 	uint32_t acl_mask;
125 	int hasmask;
126 	int dfacl_flag;
127 	ace_to_aent_state_t state;
128 	int seen; /* bitmask of all aclent_t a_type values seen */
129 } ace_list_t;
130 
131 /*
132  * Generic shellsort, from K&R (1st ed, p 58.), somewhat modified.
133  * v = Ptr to array/vector of objs
134  * n = # objs in the array
135  * s = size of each obj (must be multiples of a word size)
136  * f = ptr to function to compare two objs
137  *	returns (-1 = less than, 0 = equal, 1 = greater than
138  */
139 void
140 ksort(caddr_t v, int n, int s, int (*f)(void *, void *))
141 {
142 	int g, i, j, ii;
143 	unsigned int *p1, *p2;
144 	unsigned int tmp;
145 
146 	/* No work to do */
147 	if (v == NULL || n <= 1)
148 		return;
149 
150 	/* Sanity check on arguments */
151 	ASSERT3U(((uintptr_t)v & 0x3), ==, 0);
152 	ASSERT3S((s & 0x3), ==, 0);
153 	ASSERT3S(s, >, 0);
154 	for (g = n / 2; g > 0; g /= 2) {
155 		for (i = g; i < n; i++) {
156 			for (j = i - g; j >= 0 &&
157 			    (*f)(v + j * s, v + (j + g) * s) == 1;
158 			    j -= g) {
159 				p1 = (void *)(v + j * s);
160 				p2 = (void *)(v + (j + g) * s);
161 				for (ii = 0; ii < s / 4; ii++) {
162 					tmp = *p1;
163 					*p1++ = *p2;
164 					*p2++ = tmp;
165 				}
166 			}
167 		}
168 	}
169 }
170 
171 /*
172  * Compare two acls, all fields.  Returns:
173  * -1 (less than)
174  *  0 (equal)
175  * +1 (greater than)
176  */
177 int
178 cmp2acls(void *a, void *b)
179 {
180 	aclent_t *x = (aclent_t *)a;
181 	aclent_t *y = (aclent_t *)b;
182 
183 	/* Compare types */
184 	if (x->a_type < y->a_type)
185 		return (-1);
186 	if (x->a_type > y->a_type)
187 		return (1);
188 	/* Equal types; compare id's */
189 	if (x->a_id < y->a_id)
190 		return (-1);
191 	if (x->a_id > y->a_id)
192 		return (1);
193 	/* Equal ids; compare perms */
194 	if (x->a_perm < y->a_perm)
195 		return (-1);
196 	if (x->a_perm > y->a_perm)
197 		return (1);
198 	/* Totally equal */
199 	return (0);
200 }
201 
202 static int
203 cacl_malloc(void **ptr, size_t size)
204 {
205 	*ptr = kmem_zalloc(size, KM_SLEEP);
206 	return (0);
207 }
208 
209 
210 #define	SET_ACE(acl, index, who, mask, type, flags) { \
211 	acl[0][index].a_who = (uint32_t)who; \
212 	acl[0][index].a_type = type; \
213 	acl[0][index].a_flags = flags; \
214 	acl[0][index++].a_access_mask = mask; \
215 }
216 
217 void
218 acl_trivial_access_masks(mode_t mode, boolean_t isdir, trivial_acl_t *masks)
219 {
220 	uint32_t read_mask = ACE_READ_DATA;
221 	uint32_t write_mask = ACE_WRITE_DATA|ACE_APPEND_DATA;
222 	uint32_t execute_mask = ACE_EXECUTE;
223 
224 	(void) isdir;	/* will need this later */
225 
226 	masks->deny1 = 0;
227 	if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
228 		masks->deny1 |= read_mask;
229 	if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH)))
230 		masks->deny1 |= write_mask;
231 	if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH)))
232 		masks->deny1 |= execute_mask;
233 
234 	masks->deny2 = 0;
235 	if (!(mode & S_IRGRP) && (mode & S_IROTH))
236 		masks->deny2 |= read_mask;
237 	if (!(mode & S_IWGRP) && (mode & S_IWOTH))
238 		masks->deny2 |= write_mask;
239 	if (!(mode & S_IXGRP) && (mode & S_IXOTH))
240 		masks->deny2 |= execute_mask;
241 
242 	masks->allow0 = 0;
243 	if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH)))
244 		masks->allow0 |= read_mask;
245 	if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH)))
246 		masks->allow0 |= write_mask;
247 	if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH)))
248 		masks->allow0 |= execute_mask;
249 
250 	masks->owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL|
251 	    ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES|
252 	    ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE;
253 	if (mode & S_IRUSR)
254 		masks->owner |= read_mask;
255 	if (mode & S_IWUSR)
256 		masks->owner |= write_mask;
257 	if (mode & S_IXUSR)
258 		masks->owner |= execute_mask;
259 
260 	masks->group = ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS|
261 	    ACE_SYNCHRONIZE;
262 	if (mode & S_IRGRP)
263 		masks->group |= read_mask;
264 	if (mode & S_IWGRP)
265 		masks->group |= write_mask;
266 	if (mode & S_IXGRP)
267 		masks->group |= execute_mask;
268 
269 	masks->everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS|
270 	    ACE_SYNCHRONIZE;
271 	if (mode & S_IROTH)
272 		masks->everyone |= read_mask;
273 	if (mode & S_IWOTH)
274 		masks->everyone |= write_mask;
275 	if (mode & S_IXOTH)
276 		masks->everyone |= execute_mask;
277 }
278 
279 int
280 acl_trivial_create(mode_t mode, boolean_t isdir, ace_t **acl, int *count)
281 {
282 	int		index = 0;
283 	int		error;
284 	trivial_acl_t	masks;
285 
286 	*count = 3;
287 	acl_trivial_access_masks(mode, isdir, &masks);
288 
289 	if (masks.allow0)
290 		(*count)++;
291 	if (masks.deny1)
292 		(*count)++;
293 	if (masks.deny2)
294 		(*count)++;
295 
296 	if ((error = cacl_malloc((void **)acl, *count * sizeof (ace_t))) != 0)
297 		return (error);
298 
299 	if (masks.allow0) {
300 		SET_ACE(acl, index, -1, masks.allow0,
301 		    ACE_ACCESS_ALLOWED_ACE_TYPE, ACE_OWNER);
302 	}
303 	if (masks.deny1) {
304 		SET_ACE(acl, index, -1, masks.deny1,
305 		    ACE_ACCESS_DENIED_ACE_TYPE, ACE_OWNER);
306 	}
307 	if (masks.deny2) {
308 		SET_ACE(acl, index, -1, masks.deny2,
309 		    ACE_ACCESS_DENIED_ACE_TYPE, ACE_GROUP|ACE_IDENTIFIER_GROUP);
310 	}
311 
312 	SET_ACE(acl, index, -1, masks.owner, ACE_ACCESS_ALLOWED_ACE_TYPE,
313 	    ACE_OWNER);
314 	SET_ACE(acl, index, -1, masks.group, ACE_ACCESS_ALLOWED_ACE_TYPE,
315 	    ACE_IDENTIFIER_GROUP|ACE_GROUP);
316 	SET_ACE(acl, index, -1, masks.everyone, ACE_ACCESS_ALLOWED_ACE_TYPE,
317 	    ACE_EVERYONE);
318 
319 	return (0);
320 }
321 
322 /*
323  * ace_trivial:
324  * determine whether an ace_t acl is trivial
325  *
326  * Trivialness implies that the acl is composed of only
327  * owner, group, everyone entries.  ACL can't
328  * have read_acl denied, and write_owner/write_acl/write_attributes
329  * can only be owner@ entry.
330  */
331 int
332 ace_trivial_common(void *acep, int aclcnt,
333     uintptr_t (*walk)(void *, uintptr_t, int aclcnt,
334     uint16_t *, uint16_t *, uint32_t *))
335 {
336 	uint16_t flags;
337 	uint32_t mask;
338 	uint16_t type;
339 	uintptr_t cookie = 0;
340 
341 	while ((cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask))) {
342 		switch (flags & ACE_TYPE_FLAGS) {
343 		case ACE_OWNER:
344 		case ACE_GROUP|ACE_IDENTIFIER_GROUP:
345 		case ACE_EVERYONE:
346 			break;
347 		default:
348 			return (1);
349 
350 		}
351 
352 		if (flags & (ACE_FILE_INHERIT_ACE|
353 		    ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE|
354 		    ACE_INHERIT_ONLY_ACE))
355 			return (1);
356 
357 		/*
358 		 * Special check for some special bits
359 		 *
360 		 * Don't allow anybody to deny reading basic
361 		 * attributes or a files ACL.
362 		 */
363 		if ((mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) &&
364 		    (type == ACE_ACCESS_DENIED_ACE_TYPE))
365 			return (1);
366 
367 		/*
368 		 * Delete permissions are never set by default
369 		 */
370 		if (mask & (ACE_DELETE|ACE_DELETE_CHILD))
371 			return (1);
372 		/*
373 		 * only allow owner@ to have
374 		 * write_acl/write_owner/write_attributes/write_xattr/
375 		 */
376 		if (type == ACE_ACCESS_ALLOWED_ACE_TYPE &&
377 		    (!(flags & ACE_OWNER) && (mask &
378 		    (ACE_WRITE_OWNER|ACE_WRITE_ACL| ACE_WRITE_ATTRIBUTES|
379 		    ACE_WRITE_NAMED_ATTRS))))
380 			return (1);
381 
382 	}
383 	return (0);
384 }
385