xref: /titanic_41/usr/src/uts/common/fs/smbsrv/smb_acl.c (revision 13faa91230bde46da937bf33010b9accc5bdeb59)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Platform SDK: Security
30  *
31  * ACE Inheritance Rules
32  *
33  * The system propagates inheritable ACEs to child objects according to a
34  * set of inheritance rules. The system places inherited ACEs in the child's
35  * DACL according to the preferred order of ACEs in a DACL. For Windows
36  * 2000 or later, the system sets the INHERITED_ACE flag in all inherited ACEs.
37  *
38  * The following table shows the ACEs inherited by container and noncontainer
39  * child objects for different combinations of inheritance flags. These
40  * inheritance rules work the same for both DACLs and SACLs.
41  *
42  * Parent ACE type 				Effect on Child ACL
43  * -----------------------		-------------------
44  * OBJECT_INHERIT_ACE only 		Noncontainer child objects:
45  *					Inherited as an effective ACE.
46  *					Container child objects:
47  *					Containers inherit an inherit-only ACE
48  *					unless the NO_PROPAGATE_INHERIT_ACE bit
49  *					flag is also set.
50  *
51  * CONTAINER_INHERIT_ACE only 		Noncontainer child objects:
52  *					No effect on the child object.
53  *					Container child objects:
54  *				The child object inherits an effective ACE.
55  *				The inherited ACE is inheritable unless the
56  *				NO_PROPAGATE_INHERIT_ACE bit flag is also set.
57  *
58  * CONTAINER_INHERIT_ACE and
59  * OBJECT_INHERIT_ACE 			Noncontainer child objects:
60  *					Inherited as an effective ACE.
61  *					Container child objects:
62  *				The child object inherits an effective ACE.
63  *				The inherited ACE is inheritable unless the
64  *				NO_PROPAGATE_INHERIT_ACE bit flag is also set
65  *
66  * No inheritance flags set 	No effect on child container or noncontainer
67  *				objects.
68  *
69  * If an inherited ACE is an effective ACE for the child object, the system
70  * maps any generic rights to the specific rights for the child object.
71  * Similarly, the system maps generic SIDs, such as CREATOR_OWNER, to the
72  * appropriate SID. If an inherited ACE is an inherit-only ACE, any generic
73  * rights or generic SIDs are left unchanged so that they can be mapped
74  * appropriately when the ACE is inherited by the next generation of child
75  * objects.
76  *
77  * For a case in which a container object inherits an ACE that is both
78  * effective on the container and inheritable by its descendants, the
79  * container may inherit two ACEs. This occurs if the inheritable ACE
80  * contains generic information. The container inherits an inherit-only
81  * ACE containing the generic information and an effective-only ACE in
82  * which the generic information has been mapped.
83  */
84 
85 #include <sys/acl.h>
86 #include <smbsrv/smb_incl.h>
87 #include <smbsrv/ntsid.h>
88 #include <smbsrv/smb_fsops.h>
89 #include <smbsrv/smb_idmap.h>
90 
91 #define	ACE_FD_INHERIT_ACE (ACE_FILE_INHERIT_ACE | ACE_DIRECTORY_INHERIT_ACE)
92 
93 #define	ZACE_IS_OWNER(zace) ((zace->a_flags & ACE_TYPE_FLAGS) == ACE_OWNER)
94 #define	ZACE_IS_OWNGRP(zace) \
95 	((zace->a_flags & ACE_TYPE_FLAGS) == (ACE_IDENTIFIER_GROUP|ACE_GROUP))
96 
97 #define	ZACE_IS_USER(zace) \
98 	(((zace->a_flags & ACE_TYPE_FLAGS) == 0) || (ZACE_IS_OWNER(zace)))
99 #define	ZACE_IS_GROUP(zace) (zace->a_flags & ACE_IDENTIFIER_GROUP)
100 #define	ZACE_IS_EVERYONE(zace) (zace->a_flags & ACE_EVERYONE)
101 
102 #define	ZACE_IS_PROPAGATE(zace) \
103 	((zace->a_flags & ACE_NO_PROPAGATE_INHERIT_ACE) == 0)
104 
105 #define	ZACE_IS_CREATOR_OWNER(zace) \
106 	(ZACE_IS_USER(zace) && (zace->a_who == IDMAP_WK_CREATOR_OWNER_UID))
107 
108 #define	ZACE_IS_CREATOR_GROUP(zace) \
109 	(ZACE_IS_GROUP(zace) && (zace->a_who == IDMAP_WK_CREATOR_GROUP_GID))
110 
111 #define	ZACE_IS_CREATOR(zace) \
112 	(ZACE_IS_CREATOR_OWNER(zace) || ZACE_IS_CREATOR_GROUP(zace))
113 
114 static int smb_ace_isvalid(smb_ace_hdr_t *ace, int which_acl);
115 static int smb_ace_append_generic(smb_acl_t *acl, void *generic_ace);
116 
117 static int smb_ace_common_add(
118     smb_acl_t *acl,
119     uint8_t type,
120     uint8_t flags,
121     uint32_t access_mask,
122     nt_sid_t *sid);
123 
124 static void smb_ace_inherit(ace_t *dir_zace, ace_t *zace, int is_dir);
125 static uint16_t smb_ace_flags_tozfs(uint8_t c_flags, int isdir);
126 static uint8_t smb_ace_flags_fromzfs(uint16_t z_flags);
127 static void smb_acl_init(smb_acl_t *acl, uint16_t size, uint8_t rev);
128 
129 static int
130 smb_ace_isvalid(smb_ace_hdr_t *ace, int which_acl)
131 {
132 	uint16_t min_len;
133 	smb_ace_t *p;
134 
135 	min_len = sizeof (smb_ace_hdr_t);
136 
137 	if (ace->se_size < min_len)
138 		return (0);
139 
140 	if (smb_ace_is_access(ace->se_type) &&
141 	    (which_acl != SMB_DACL_SECINFO)) {
142 		return (0);
143 	}
144 
145 	if (smb_ace_is_audit(ace->se_type) &&
146 	    (which_acl != SMB_SACL_SECINFO)) {
147 		return (0);
148 	}
149 
150 	if (smb_ace_is_generic(ace->se_type)) {
151 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
152 		p = (smb_ace_t *)ace;
153 
154 		if (ace->se_size < sizeof (*p))
155 			return (0);	/* won't handle empty SubAuthority[] */
156 
157 		if (nt_sid_is_valid(&p->se_sid) == 0)
158 			return (0);
159 
160 		min_len += sizeof (p->se_mask);
161 		min_len += nt_sid_length(&p->se_sid);
162 
163 		if (ace->se_size < min_len)
164 			return (0);
165 	}
166 
167 	/*
168 	 * XXX object-specific ACE validation will be added later.
169 	 */
170 	return (1);
171 }
172 
173 int
174 smb_acl_isvalid(smb_acl_t *acl, int which_acl)
175 {
176 	uint16_t	min_len;
177 	unsigned char	*scan;
178 	unsigned char	*scan_end;
179 	smb_ace_hdr_t	*ace;
180 	uint16_t	count = 0;
181 
182 	min_len = sizeof (smb_acl_t);
183 
184 	if (acl->sl_size < min_len)
185 		return (0);
186 
187 	if (acl->sl_revision != ACL_REVISION) {
188 		/*
189 		 * XXX we are rejecting ACLs with object-specific ACEs for now
190 		 */
191 		return (0);
192 	}
193 
194 	scan = (unsigned char *) &acl[0];
195 	scan_end = scan + acl->sl_size;
196 	scan = (unsigned char *) &acl[1];	/* skip Acl header */
197 
198 	while (count < acl->sl_acecnt && scan < scan_end) {
199 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
200 		ace = (smb_ace_hdr_t *)scan;
201 
202 		if (scan + sizeof (smb_ace_hdr_t) >= scan_end)
203 			return (0);
204 
205 		if (scan + ace->se_size > scan_end)
206 			return (0);	/* overflow */
207 
208 		if (!smb_ace_isvalid(ace, which_acl))
209 			return (0);
210 
211 		scan += ace->se_size;
212 		count++;
213 	}
214 
215 	return (1);
216 }
217 
218 
219 static void
220 smb_acl_init(smb_acl_t *acl, uint16_t size, uint8_t rev)
221 {
222 	bzero(acl, size);
223 	acl->sl_revision = rev;
224 	acl->sl_size = size;
225 }
226 
227 uint16_t
228 smb_acl_len(smb_acl_t *acl)
229 {
230 	smb_ace_hdr_t *ace;
231 	unsigned char *scan_beg;
232 	unsigned char *scan_end;
233 	unsigned char *scan;
234 	uint16_t length;
235 	uint16_t count;
236 
237 	scan_beg = (unsigned char *) &acl[0];
238 	scan_end = scan_beg + acl->sl_size;
239 	scan = (unsigned char *) &acl[1];
240 	length   = sizeof (smb_acl_t);
241 	count    = 0;
242 
243 	while ((count < acl->sl_acecnt) && (scan < scan_end)) {
244 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
245 		ace = (smb_ace_hdr_t *)scan;
246 		length += ace->se_size;
247 		scan += ace->se_size;
248 		count++;
249 	}
250 
251 	return (length);
252 }
253 
254 /*
255  * Append the generic ACE to the ACL. This is used to put any
256  * kind of ACE on the ACL so the argument is declared as a void*. We cast it
257  * to an ACCESS_ALLOWED_ACE just because there is no sense of a generic ACE.
258  */
259 static int
260 smb_ace_append_generic(smb_acl_t *acl, void *generic_ace)
261 {
262 	smb_ace_t *ace = (smb_ace_t *)generic_ace;
263 	uint16_t acl_len = smb_acl_len(acl);
264 	unsigned char *scan = (uchar_t *)acl;
265 
266 	if ((acl_len + ace->se_header.se_size) > acl->sl_size) {
267 		/* no room in the acl for this ace */
268 		return (0);
269 	}
270 
271 	/* append the ace to the acl and inc ace count */
272 	bcopy(ace, &scan[acl_len], ace->se_header.se_size);
273 	acl->sl_acecnt++;
274 
275 	return (1);
276 }
277 
278 /*
279  * Helper for the ACL sort routine
280  */
281 typedef struct smb_ace_entry {
282 	smb_ace_t	*e_ace;
283 	list_node_t	e_node;
284 } smb_ace_entry_t;
285 
286 /*
287  * ACE groups within a DACL
288  *
289  * This is from lower to higher ACE order priority
290  */
291 #define	SMB_AG_START		0
292 #define	SMB_AG_ALW_INHRT	0
293 #define	SMB_AG_DNY_INHRT	1
294 #define	SMB_AG_ALW_DRCT		2
295 #define	SMB_AG_DNY_DRCT		3
296 #define	SMB_AG_NUM		4
297 
298 /*
299  * smb_acl_do_sort
300  *
301  * Sorts the given ACL, acl, and returns the result
302  * in a newly allocated memory.
303  *
304  * The following is an excerpt from MSDN website.
305  *
306  * Order of ACEs in a DACL
307  *
308  * For Windows NT versions 4.0 and earlier, the preferred order of ACEs
309  * is simple: In a DACL, all access-denied ACEs should precede any
310  * access-allowed ACEs.
311  *
312  * For Windows 2000 or later, the proper order of ACEs is more complicated
313  * because of the introduction of object-specific ACEs and automatic
314  * inheritance.
315  *
316  * The following describes the preferred order:
317  *
318  * To ensure that noninherited ACEs have precedence over inherited ACEs,
319  * place all noninherited ACEs in a group before any inherited ACEs. This
320  * ordering ensures, for example, that a noninherited access-denied ACE
321  * is enforced regardless of any inherited ACE that allows access.
322  * Within the groups of noninherited ACEs and inherited ACEs, order ACEs
323  * according to ACE type, as the following shows:
324  * 	. Access-denied ACEs that apply to the object itself
325  * 	. Access-denied ACEs that apply to a subobject of the
326  *	  object, such as a property set or property
327  * 	. Access-allowed ACEs that apply to the object itself
328  * 	. Access-allowed ACEs that apply to a subobject of the object
329  *
330  * Of course, not all ACE types are required in an ACL.
331  */
332 static smb_acl_t *
333 smb_acl_do_sort(smb_acl_t *acl, list_t *ace_grps)
334 {
335 	smb_acl_t *sorted_acl;
336 	smb_ace_entry_t *nae;
337 	int i;
338 
339 	sorted_acl = kmem_alloc(acl->sl_size, KM_SLEEP);
340 	*sorted_acl = *acl;
341 
342 	/* start with no ACE in the sorted ACL */
343 	sorted_acl->sl_acecnt = 0;
344 
345 	/*
346 	 * start with highest priority ACE group and append
347 	 * the ACEs to the ACL.
348 	 */
349 	for (i = SMB_AG_NUM - 1; i >= SMB_AG_START; i--) {
350 		nae = list_head(&ace_grps[i]);
351 		while (nae) {
352 			if (!smb_ace_append_generic(sorted_acl, nae->e_ace)) {
353 				kmem_free(sorted_acl, acl->sl_size);
354 				return (NULL);
355 			}
356 			nae = list_next(&ace_grps[i], nae);
357 		}
358 	}
359 
360 	return (sorted_acl);
361 }
362 
363 /*
364  * smb_acl_need_sort
365  *
366  * Here is the desired ACE order
367  *
368  * deny-direct, allow-direct, deny-inherited, allow-inherited
369  *
370  * If any ace has been encountered which belongs to a group
371  * with lower priority of the specified ace_grp then the acl
372  * should be sorted.
373  */
374 static int
375 smb_acl_need_sort(list_t *ace_grps, int ace_grp)
376 {
377 	int i;
378 
379 	for (i = SMB_AG_START; i < ace_grp; i++)
380 		if (!list_is_empty(&ace_grps[i]))
381 			return (1);
382 
383 	return (0);
384 }
385 
386 /*
387  * smb_acl_sort
388  *
389  * Returns NULL upon failure.
390  * Returns pointer to the passed (original) acl if no sort is required.
391  * Returns pointer to a new acl upon successful sort in which case the
392  * caller is responsible for freeing the allocated memory.
393  */
394 smb_acl_t *
395 smb_acl_sort(smb_acl_t *acl)
396 {
397 	smb_acl_t *sorted_acl;
398 	smb_ace_t *ace;
399 	smb_ace_entry_t *ace_list;
400 	int ace_list_size;
401 	list_t ace_grps[SMB_AG_NUM];
402 	int ag;
403 	int do_sort = 0;
404 	uint16_t i;
405 	uint8_t ace_flags;
406 
407 	ASSERT(acl);
408 
409 	if (acl->sl_acecnt == 0) {
410 		/*
411 		 * ACL with no entry is a valid ACL and it means
412 		 * no access for anybody.
413 		 */
414 		return (acl);
415 	}
416 
417 	for (i = SMB_AG_START; i < SMB_AG_NUM; i++) {
418 		list_create(&ace_grps[i], sizeof (smb_ace_entry_t),
419 		    offsetof(smb_ace_entry_t, e_node));
420 	}
421 
422 	/*
423 	 * Allocate the helper entries to group the ACEs based on
424 	 * the desired priorities.
425 	 */
426 	ace_list_size = sizeof (smb_ace_entry_t) * acl->sl_acecnt;
427 	ace_list = kmem_alloc(ace_list_size, KM_SLEEP);
428 
429 	for (i = 0; i < acl->sl_acecnt; ++i) {
430 		ace_list[i].e_ace = smb_ace_get(acl, i);
431 		ace = ace_list[i].e_ace;
432 		ASSERT(ace);
433 
434 		ace_flags = ace->se_header.se_flags;
435 
436 		switch (ace->se_header.se_type) {
437 		case ACCESS_DENIED_ACE_TYPE:
438 			if (ace_flags & INHERITED_ACE) {
439 				ag = SMB_AG_DNY_INHRT;
440 				do_sort |= smb_acl_need_sort(ace_grps, ag);
441 			} else {
442 				ag = SMB_AG_DNY_DRCT;
443 				do_sort |= smb_acl_need_sort(ace_grps, ag);
444 			}
445 			break;
446 
447 		case ACCESS_ALLOWED_ACE_TYPE:
448 			if (ace_flags & INHERITED_ACE) {
449 				ag = SMB_AG_ALW_INHRT;
450 			} else {
451 				ag = SMB_AG_ALW_DRCT;
452 				do_sort |= smb_acl_need_sort(ace_grps, ag);
453 			}
454 			break;
455 
456 		default:
457 			/*
458 			 * This is the lowest priority group so we put
459 			 * evertything unknown here.
460 			 */
461 			ag = SMB_AG_ALW_INHRT;
462 			break;
463 		}
464 
465 		/* Put the element on the appropriate list */
466 		list_insert_tail(&ace_grps[ag], &ace_list[i]);
467 	}
468 
469 	if (do_sort)
470 		sorted_acl = smb_acl_do_sort(acl, ace_grps);
471 	else
472 		sorted_acl = acl;
473 
474 	for (i = SMB_AG_START; i < SMB_AG_NUM; i++) {
475 		void *ent;
476 		list_t *alist = &ace_grps[i];
477 
478 		while ((ent = list_head(alist)) != NULL)
479 			list_remove(alist, ent);
480 		list_destroy(alist);
481 	}
482 
483 	kmem_free(ace_list, ace_list_size);
484 
485 	return (sorted_acl);
486 }
487 
488 static int
489 smb_ace_common_add(
490     smb_acl_t *acl,
491     uint8_t type,
492     uint8_t flags,
493     uint32_t access_mask,
494     nt_sid_t *sid)
495 {
496 	smb_ace_t *ace;
497 	unsigned char *scan = (unsigned char *) acl;
498 	uint16_t used = smb_acl_len(acl);
499 	uint16_t sid_len = nt_sid_length(sid);
500 	uint16_t size;
501 
502 	size = sizeof (ace->se_header) + sizeof (ace->se_mask) + sid_len;
503 
504 	if (size + used > acl->sl_size) {
505 		/* won't fit */
506 		return (0);
507 	}
508 
509 	/*LINTED E_BAD_PTR_CAST_ALIGN*/
510 	ace = (smb_ace_t *)&scan[used];
511 
512 	ace->se_header.se_type  = type;
513 	ace->se_header.se_flags = flags;
514 	ace->se_header.se_size  = size;
515 	ace->se_mask = access_mask;
516 	bcopy(sid, &ace->se_sid, sid_len);
517 
518 	acl->sl_acecnt++;
519 
520 	return (1);
521 }
522 
523 smb_ace_t *
524 smb_ace_get(smb_acl_t *acl, uint16_t idx)
525 {
526 	smb_ace_t *ace;
527 	unsigned char *scan_beg = (unsigned char *) &acl[0];
528 	unsigned char *scan_end = scan_beg + acl->sl_size;
529 	unsigned char *scan = (unsigned char *) &acl[1];
530 	uint16_t count = 0;
531 
532 	if (idx >= acl->sl_acecnt)
533 		return (NULL);
534 
535 	while (count <= idx && scan < scan_end) {
536 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
537 		ace = (smb_ace_t *)scan;
538 
539 		if (count == idx) {
540 			return (ace);
541 		}
542 
543 		scan += ace->se_header.se_size;
544 		count++;
545 	}
546 
547 	return (NULL);
548 }
549 
550 int
551 smb_acl_copy(uint16_t buflen, smb_acl_t *dst_acl, smb_acl_t *src_acl)
552 {
553 	smb_ace_hdr_t *dst_ace;
554 	smb_ace_hdr_t *src_ace;
555 	unsigned char *scan = (unsigned char *) &src_acl[1];
556 	unsigned char *dest_beg = (unsigned char *) &dst_acl[0];
557 	unsigned char *dest_end;
558 	unsigned char *dest = (unsigned char *) &dst_acl[1];
559 	uint16_t count = 0;
560 	uint16_t n_bytes;
561 
562 	n_bytes = smb_acl_len(src_acl);
563 	if (n_bytes > buflen)
564 		return (0);
565 
566 	dest_end = dest_beg + n_bytes;
567 
568 	dst_acl->sl_revision = src_acl->sl_revision;
569 	dst_acl->sl_sbz1 = 0;
570 	dst_acl->sl_size = n_bytes;
571 	dst_acl->sl_acecnt = 0;
572 	dst_acl->sl_sbz2 = 0;
573 
574 	while (count < src_acl->sl_acecnt && dest < dest_end) {
575 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
576 		src_ace = (smb_ace_hdr_t *)scan;
577 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
578 		dst_ace = (smb_ace_hdr_t *)dest;
579 		bcopy(src_ace, dst_ace, src_ace->se_size);
580 		dest += dst_ace->se_size;
581 		dst_acl->sl_acecnt++;
582 		scan += src_ace->se_size;
583 		count++;
584 	}
585 
586 	/*LINTED E_PTRDIFF_OVERFLOW*/
587 	return (dest - dest_beg);
588 }
589 
590 /*
591  * smb_ace_len
592  *
593  * Returns the length of an ACE with the given SID
594  *
595  * struct smb_ace {
596  *	smb_ace_hdr_t se_header;
597  *	uint32_t se_mask;
598  *	nt_sid_t se_sid;
599  * };
600  */
601 uint16_t
602 smb_ace_len(nt_sid_t *sid)
603 {
604 	ASSERT(sid);
605 
606 	return (sizeof (smb_ace_hdr_t)
607 	    + sizeof (uint32_t) + nt_sid_length(sid));
608 }
609 
610 /*
611  * smb_ace_mask_g2s
612  *
613  * Converts generic access bits in the given mask (if any)
614  * to file specific bits. Generic access masks shouldn't be
615  * stored in filesystem ACEs.
616  */
617 uint32_t
618 smb_ace_mask_g2s(DWORD mask)
619 {
620 	if (mask & GENERIC_ALL) {
621 		mask &= ~(GENERIC_ALL | GENERIC_READ | GENERIC_WRITE
622 		    | GENERIC_EXECUTE);
623 
624 		mask |= FILE_ALL_ACCESS;
625 		return (mask);
626 	}
627 
628 	if (mask & GENERIC_READ) {
629 		mask &= ~GENERIC_READ;
630 		mask |= FILE_GENERIC_READ;
631 	}
632 
633 	if (mask & GENERIC_WRITE) {
634 		mask &= ~GENERIC_WRITE;
635 		mask |= FILE_GENERIC_WRITE;
636 	}
637 
638 	if (mask & GENERIC_EXECUTE) {
639 		mask &= ~GENERIC_EXECUTE;
640 		mask |= FILE_GENERIC_EXECUTE;
641 	}
642 
643 	return (mask);
644 }
645 
646 /*
647  * smb_acl_getsids
648  *
649  * Batch all the uid/gid in given ZFS ACL to get their corresponding SIDs.
650  */
651 static idmap_stat
652 smb_acl_getsids(smb_idmap_batch_t *sib, acl_t *zacl, uid_t uid, gid_t gid)
653 {
654 	ace_t *zace;
655 	idmap_stat idm_stat;
656 	smb_idmap_t *sim;
657 	uid_t id;
658 	int i, idtype;
659 
660 	sim = sib->sib_maps;
661 
662 	for (i = 0, zace = zacl->acl_aclp; i < zacl->acl_cnt;
663 	    zace++, i++, sim++) {
664 		switch (zace->a_flags & ACE_TYPE_FLAGS) {
665 		case ACE_OWNER:
666 			id = uid;
667 			idtype = SMB_IDMAP_USER;
668 			break;
669 
670 		case (ACE_GROUP | ACE_IDENTIFIER_GROUP):
671 			/* owning group */
672 			id = gid;
673 			idtype = SMB_IDMAP_GROUP;
674 			break;
675 
676 		case ACE_IDENTIFIER_GROUP:
677 			/* regular group */
678 			id = zace->a_who;
679 			idtype = SMB_IDMAP_GROUP;
680 			break;
681 
682 		case ACE_EVERYONE:
683 			idtype = SMB_IDMAP_EVERYONE;
684 			break;
685 
686 		default:
687 			/* user entry */
688 			id = zace->a_who;
689 			idtype = SMB_IDMAP_USER;
690 		}
691 
692 		idm_stat = smb_idmap_batch_getsid(sib->sib_idmaph, sim,
693 		    id, idtype);
694 
695 		if (idm_stat != IDMAP_SUCCESS) {
696 			return (idm_stat);
697 		}
698 	}
699 
700 	idm_stat = smb_idmap_batch_getmappings(sib);
701 	return (idm_stat);
702 }
703 
704 /*
705  * smb_acl_grow
706  *
707  * Grow the acl size by given number of bytes in 'grow'
708  * Returns pointer to the newly allocated memory.
709  */
710 static smb_acl_t *
711 smb_acl_grow(smb_acl_t *acl, uint16_t grow)
712 {
713 	smb_acl_t *new_acl;
714 	uint16_t smb_aclsz;
715 
716 	ASSERT(acl);
717 
718 	smb_aclsz = acl->sl_size;
719 	new_acl = kmem_alloc(smb_aclsz + grow, KM_SLEEP);
720 	(void) memcpy(new_acl, acl, smb_aclsz);
721 	kmem_free(acl, smb_aclsz);
722 	new_acl->sl_size = smb_aclsz + grow;
723 
724 	return (new_acl);
725 }
726 
727 /*
728  * smb_acl_from_zfs
729  *
730  * Converts given ZFS ACL to a Windows ACL.
731  *
732  * A pointer to allocated memory for the Win ACL will be
733  * returned upon successful conversion.
734  */
735 smb_acl_t *
736 smb_acl_from_zfs(acl_t *zacl, uid_t uid, gid_t gid)
737 {
738 	ace_t *zace;
739 	int numaces;
740 	smb_acl_t *acl;
741 	uint16_t smb_aclsz;
742 	smb_idmap_batch_t sib;
743 	smb_idmap_t *sim;
744 	idmap_stat idm_stat;
745 	int status;
746 
747 	idm_stat = smb_idmap_batch_create(&sib, zacl->acl_cnt,
748 	    SMB_IDMAP_ID2SID);
749 	if (idm_stat != IDMAP_SUCCESS)
750 		return (NULL);
751 
752 	if (smb_acl_getsids(&sib, zacl, uid, gid) != IDMAP_SUCCESS) {
753 		smb_idmap_batch_destroy(&sib);
754 		return (NULL);
755 	}
756 
757 	smb_aclsz = sizeof (smb_acl_t);
758 
759 	acl = kmem_alloc(smb_aclsz, KM_SLEEP);
760 	smb_acl_init(acl, smb_aclsz, ACL_REVISION);
761 
762 	sim = sib.sib_maps;
763 	for (numaces = 0, zace = zacl->acl_aclp;
764 	    numaces < zacl->acl_cnt;
765 	    zace++, numaces++, sim++) {
766 		ASSERT(sim->sim_sid);
767 		if (sim->sim_sid == NULL) {
768 			kmem_free(acl, acl->sl_size);
769 			acl = NULL;
770 			break;
771 		}
772 
773 		/* Make room for this ACE */
774 		acl = smb_acl_grow(acl, smb_ace_len(sim->sim_sid));
775 
776 		status = smb_ace_common_add(acl,
777 		    zace->a_type,
778 		    smb_ace_flags_fromzfs(zace->a_flags),
779 		    zace->a_access_mask,
780 		    sim->sim_sid);
781 
782 		if (status == 0) {
783 			kmem_free(acl, acl->sl_size);
784 			acl = NULL;
785 			break;
786 		}
787 	}
788 
789 	smb_idmap_batch_destroy(&sib);
790 	return (acl);
791 }
792 
793 /*
794  * SID for Everyone group: S-1-1-0.
795  */
796 nt_sid_t everyone_sid = {
797 	NT_SID_REVISION,
798 	1,
799 	NT_SECURITY_WORLD_AUTH,
800 	{ 0 }
801 };
802 
803 /*
804  * smb_acl_null_empty
805  *
806  * NULL DACL means everyone full-access
807  * Empty DACL means everyone full-deny
808  *
809  * ZFS ACL must have at least one entry so smb server has
810  * to simulate the aforementioned expected behavior by adding
811  * an entry in case the requested DACL is null or empty. Adding
812  * a everyone full-deny entry has proved to be problematic in
813  * tests since a deny entry takes precedence over allow entries.
814  * So, instead of adding a everyone full-deny, an owner ACE with
815  * owner implicit permissions will be set.
816  */
817 acl_t *
818 smb_acl_null_empty(int null)
819 {
820 	acl_t *zacl;
821 	ace_t *zace;
822 
823 	zacl = smb_fsop_aclalloc(1, ACL_AUTO_INHERIT);
824 	zace = zacl->acl_aclp;
825 
826 	zace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
827 	if (null) {
828 		zace->a_access_mask = ACE_ALL_PERMS;
829 		zace->a_flags = ACE_EVERYONE;
830 	} else {
831 		zace->a_access_mask = ACE_READ_ACL | ACE_WRITE_ACL |
832 		    ACE_READ_ATTRIBUTES;
833 		zace->a_flags = ACE_OWNER;
834 	}
835 
836 	return (zacl);
837 }
838 
839 /*
840  * smb_acl_to_zfs
841  *
842  * Converts given Windows ACL to a ZFS ACL.
843  *
844  * fs_acl will contain a pointer to the created ZFS ACL.
845  * The allocated memory should be freed by calling
846  * smb_fsop_aclfree().
847  *
848  * Since the output parameter, fs_acl, is allocated in this
849  * function, the caller has to make sure *fs_acl is NULL which
850  * means it's not pointing to any memory.
851  */
852 uint32_t
853 smb_acl_to_zfs(smb_acl_t *acl, uint32_t flags, int which_acl, acl_t **fs_acl)
854 {
855 	smb_ace_t *ace;
856 	acl_t *zacl;
857 	ace_t *zace;
858 	smb_idmap_batch_t sib;
859 	smb_idmap_t *sim;
860 	idmap_stat idm_stat;
861 	int i, isdir;
862 
863 	ASSERT(fs_acl);
864 	ASSERT(*fs_acl == NULL);
865 
866 	if (acl && !smb_acl_isvalid(acl, which_acl))
867 		return (NT_STATUS_INVALID_ACL);
868 
869 	if ((acl == NULL) || (acl->sl_acecnt == 0)) {
870 		if (which_acl == SMB_DACL_SECINFO) {
871 			*fs_acl = smb_acl_null_empty(acl == NULL);
872 		}
873 
874 		return (NT_STATUS_SUCCESS);
875 	}
876 
877 	idm_stat = smb_idmap_batch_create(&sib, acl->sl_acecnt,
878 	    SMB_IDMAP_SID2ID);
879 	if (idm_stat != IDMAP_SUCCESS)
880 		return (NT_STATUS_INTERNAL_ERROR);
881 
882 	isdir = ((flags & ACL_IS_DIR) == ACL_IS_DIR);
883 
884 	zacl = smb_fsop_aclalloc(acl->sl_acecnt, flags);
885 
886 	zace = zacl->acl_aclp;
887 	sim = sib.sib_maps;
888 
889 	for (i = 0; ace = smb_ace_get(acl, i); i++, zace++, sim++) {
890 		zace->a_type = ace->se_header.se_type & ACE_ALL_TYPES;
891 		zace->a_access_mask = smb_ace_mask_g2s(ace->se_mask);
892 		zace->a_flags = smb_ace_flags_tozfs(ace->se_header.se_flags,
893 		    isdir);
894 
895 		if (nt_sid_is_equal(&ace->se_sid, &everyone_sid))
896 			zace->a_flags |= ACE_EVERYONE;
897 		else {
898 			sim->sim_id = &zace->a_who;
899 			idm_stat = smb_idmap_batch_getid(sib.sib_idmaph, sim,
900 			    &ace->se_sid, -1);
901 
902 			if (idm_stat != IDMAP_SUCCESS) {
903 				smb_fsop_aclfree(zacl);
904 				smb_idmap_batch_destroy(&sib);
905 				return (NT_STATUS_INTERNAL_ERROR);
906 			}
907 		}
908 	}
909 
910 	idm_stat = smb_idmap_batch_getmappings(&sib);
911 	if (idm_stat != IDMAP_SUCCESS) {
912 		smb_fsop_aclfree(zacl);
913 		smb_idmap_batch_destroy(&sib);
914 		return (NT_STATUS_NONE_MAPPED);
915 	}
916 
917 	/*
918 	 * Set the ACEs group flag based on the type of ID returned.
919 	 */
920 	zace = zacl->acl_aclp;
921 	sim = sib.sib_maps;
922 	for (i = 0; i < acl->sl_acecnt; i++, zace++, sim++) {
923 		if (zace->a_flags & ACE_EVERYONE)
924 			continue;
925 
926 		if (sim->sim_idtype == SMB_IDMAP_GROUP)
927 			zace->a_flags |= ACE_IDENTIFIER_GROUP;
928 	}
929 
930 	smb_idmap_batch_destroy(&sib);
931 
932 	*fs_acl = zacl;
933 	return (NT_STATUS_SUCCESS);
934 }
935 
936 /*
937  * smb_acl_inheritable
938  *
939  * Checks to see if there are any inheritable ACEs in the
940  * given ZFS ACL. Returns the number of inheritable ACEs.
941  *
942  * The inherited ACL could be different based on the type of
943  * new object (file/dir) specified by 'is_dir'.
944  *
945  * Note that the input ACL is a ZFS ACL not Windows ACL.
946  *
947  * Any ACE except creator owner/group:
948  *
949  *  FI   DI   NP   #F  #D
950  * ---- ---- ---- ---- ----
951  *  -    -    ?    0    0
952  *  X    -    -    1    1
953  *  X    -    X    1    0
954  *  -    X    -    0    1
955  *  -    X    X    0    1
956  *  X    X    -    1    1
957  *  X    X    X    1    1
958  *
959  * Creator owner/group ACE:
960  *
961  *  FI   DI   NP   #F  #D
962  * ---- ---- ---- ---- ----
963  *  -    -    ?    0    0
964  *  X    -    -    1r   1c
965  *  X    -    X    1r   0
966  *  -    X    -    0    2
967  *  -    X    X    0    1r
968  *  X    X    -    1r   2
969  *  X    X    X    1r   1r
970  *
971  * Legend:
972  *
973  *  FI: File Inherit
974  *  DI: Dir Inherit
975  *  NP: No Propagate
976  *  #F: #ACE for a new file
977  *  #D: #ACE for a new dir
978  *
979  *   X: bit is set
980  *   -: bit is not set
981  *   ?: don't care
982  *
983  *  1r: one owner/group ACE
984  *  1c: one creator owner/group ACE
985  */
986 static int
987 smb_acl_inheritable(acl_t *zacl, int is_dir)
988 {
989 	int numaces;
990 	int num_inheritable = 0;
991 	ace_t *zace;
992 
993 	if (zacl == NULL)
994 		return (0);
995 
996 	for (numaces = 0, zace = zacl->acl_aclp;
997 	    numaces < zacl->acl_cnt;
998 	    zace++, numaces++) {
999 		switch (zace->a_flags & ACE_FD_INHERIT_ACE) {
1000 		case (ACE_FILE_INHERIT_ACE | ACE_DIRECTORY_INHERIT_ACE):
1001 			/*
1002 			 * Files inherit an effective ACE.
1003 			 *
1004 			 * Dirs inherit an effective ACE.
1005 			 * The inherited ACE is inheritable unless the
1006 			 * ACE_NO_PROPAGATE_INHERIT_ACE bit flag is also set
1007 			 */
1008 			num_inheritable++;
1009 
1010 			if (is_dir && ZACE_IS_CREATOR(zace) &&
1011 			    (ZACE_IS_PROPAGATE(zace))) {
1012 				num_inheritable++;
1013 			}
1014 			break;
1015 
1016 		case ACE_FILE_INHERIT_ACE:
1017 			/*
1018 			 * Files inherit as an effective ACE.
1019 			 *
1020 			 * Dirs inherit an inherit-only ACE
1021 			 * unless the ACE_NO_PROPAGATE_INHERIT_ACE bit
1022 			 * flag is also set.
1023 			 */
1024 			if (is_dir == 0)
1025 				num_inheritable++;
1026 			else if (ZACE_IS_PROPAGATE(zace))
1027 				num_inheritable++;
1028 			break;
1029 
1030 		case ACE_DIRECTORY_INHERIT_ACE:
1031 			/*
1032 			 * No effect on files
1033 			 *
1034 			 * Dirs inherit an effective ACE.
1035 			 * The inherited ACE is inheritable unless the
1036 			 * ACE_NO_PROPAGATE_INHERIT_ACE bit flag is also set.
1037 			 */
1038 			if (is_dir == 0)
1039 				break;
1040 
1041 			num_inheritable++;
1042 
1043 			if (ZACE_IS_CREATOR(zace) &&
1044 			    (ZACE_IS_PROPAGATE(zace)))
1045 				num_inheritable++;
1046 			break;
1047 
1048 		default:
1049 			break;
1050 		}
1051 	}
1052 
1053 	return (num_inheritable);
1054 }
1055 
1056 #define	DEFAULT_DACL_ACENUM	2
1057 /*
1058  * Default ACL:
1059  *    owner: full access
1060  *    SYSTEM: full access
1061  */
1062 static ace_t default_dacl[DEFAULT_DACL_ACENUM] = {
1063 	{ (uid_t)-1, ACE_ALL_PERMS, 0, ACE_ACCESS_ALLOWED_ACE_TYPE },
1064 	{ IDMAP_WK_LOCAL_SYSTEM_GID, ACE_ALL_PERMS, ACE_IDENTIFIER_GROUP,
1065 	    ACE_ACCESS_ALLOWED_ACE_TYPE }
1066 };
1067 
1068 /*
1069  * smb_acl_inherit
1070  *
1071  * Manufacture the inherited ACL from the given ACL considering
1072  * the new object type (file/dir) specified by 'is_dir'. The
1073  * returned ACL is used in smb_fsop_create/smb_fsop_mkdir functions.
1074  * This function implements Windows inheritance rules.
1075  *
1076  * Note that the in/our ACLs are ZFS ACLs not Windows ACLs
1077  */
1078 acl_t *
1079 smb_acl_inherit(acl_t *dir_zacl, int is_dir, int which_acl, uid_t owner_uid)
1080 {
1081 	boolean_t use_default = B_FALSE;
1082 	int num_inheritable = 0;
1083 	int numaces;
1084 	ace_t *dir_zace;
1085 	acl_t *new_zacl;
1086 	ace_t *new_zace;
1087 
1088 	num_inheritable = smb_acl_inheritable(dir_zacl, is_dir);
1089 
1090 	if (num_inheritable == 0) {
1091 		if (which_acl == SMB_DACL_SECINFO) {
1092 			/* No inheritable access ACEs -> default DACL */
1093 			num_inheritable = DEFAULT_DACL_ACENUM;
1094 			use_default = B_TRUE;
1095 		} else {
1096 			return (NULL);
1097 		}
1098 	}
1099 
1100 	new_zacl = smb_fsop_aclalloc(num_inheritable, ACL_AUTO_INHERIT);
1101 	new_zace = new_zacl->acl_aclp;
1102 
1103 	if (use_default) {
1104 		bcopy(default_dacl, new_zacl->acl_aclp, sizeof (default_dacl));
1105 		new_zace->a_who = owner_uid;
1106 		return (new_zacl);
1107 	}
1108 
1109 	for (numaces = 0, dir_zace = dir_zacl->acl_aclp;
1110 	    numaces < dir_zacl->acl_cnt;
1111 	    dir_zace++, numaces++) {
1112 		switch (dir_zace->a_flags & ACE_FD_INHERIT_ACE) {
1113 		case (ACE_FILE_INHERIT_ACE | ACE_DIRECTORY_INHERIT_ACE):
1114 			/*
1115 			 * Files inherit an effective ACE.
1116 			 *
1117 			 * Dirs inherit an effective ACE.
1118 			 * The inherited ACE is inheritable unless the
1119 			 * ACE_NO_PROPAGATE_INHERIT_ACE bit flag is also set
1120 			 */
1121 			smb_ace_inherit(dir_zace, new_zace, is_dir);
1122 			new_zace++;
1123 
1124 			if (is_dir && ZACE_IS_CREATOR(dir_zace) &&
1125 			    (ZACE_IS_PROPAGATE(dir_zace))) {
1126 				*new_zace = *dir_zace;
1127 				new_zace->a_flags |= (ACE_INHERIT_ONLY_ACE |
1128 				    ACE_INHERITED_ACE);
1129 				new_zace++;
1130 			}
1131 			break;
1132 
1133 		case ACE_FILE_INHERIT_ACE:
1134 			/*
1135 			 * Files inherit as an effective ACE.
1136 			 *
1137 			 * Dirs inherit an inherit-only ACE
1138 			 * unless the ACE_NO_PROPAGATE_INHERIT_ACE bit
1139 			 * flag is also set.
1140 			 */
1141 			if (is_dir == 0) {
1142 				smb_ace_inherit(dir_zace, new_zace, is_dir);
1143 				new_zace++;
1144 			} else if (ZACE_IS_PROPAGATE(dir_zace)) {
1145 				*new_zace = *dir_zace;
1146 				new_zace->a_flags |= (ACE_INHERIT_ONLY_ACE |
1147 				    ACE_INHERITED_ACE);
1148 				new_zace++;
1149 			}
1150 			break;
1151 
1152 		case ACE_DIRECTORY_INHERIT_ACE:
1153 			/*
1154 			 * No effect on files
1155 			 *
1156 			 * Dirs inherit an effective ACE.
1157 			 * The inherited ACE is inheritable unless the
1158 			 * ACE_NO_PROPAGATE_INHERIT_ACE bit flag is also set.
1159 			 */
1160 			if (is_dir == 0)
1161 				break;
1162 
1163 			smb_ace_inherit(dir_zace, new_zace, is_dir);
1164 			new_zace++;
1165 
1166 			if (ZACE_IS_CREATOR(dir_zace) &&
1167 			    (ZACE_IS_PROPAGATE(dir_zace))) {
1168 				*new_zace = *dir_zace;
1169 				new_zace->a_flags |= (ACE_INHERIT_ONLY_ACE |
1170 				    ACE_INHERITED_ACE);
1171 				new_zace++;
1172 			}
1173 
1174 			break;
1175 
1176 		default:
1177 			break;
1178 		}
1179 	}
1180 
1181 	return (new_zacl);
1182 }
1183 
1184 static void
1185 smb_ace_inherit(ace_t *dir_zace, ace_t *zace, int is_dir)
1186 {
1187 	*zace = *dir_zace;
1188 	if (!(is_dir && ZACE_IS_PROPAGATE(dir_zace)))
1189 		zace->a_flags &= ~ACE_INHERIT_FLAGS;
1190 	zace->a_flags |= ACE_INHERITED_ACE;
1191 
1192 	/*
1193 	 * Replace creator owner/group ACEs with
1194 	 * actual owner/group ACEs.
1195 	 */
1196 	if (ZACE_IS_CREATOR_OWNER(dir_zace)) {
1197 		zace->a_who = (uid_t)-1;
1198 		zace->a_flags |= ACE_OWNER;
1199 	} else if (ZACE_IS_CREATOR_GROUP(dir_zace)) {
1200 		zace->a_who = (uid_t)-1;
1201 		zace->a_flags |= ACE_GROUP;
1202 	}
1203 }
1204 
1205 static uint16_t
1206 smb_ace_flags_tozfs(uint8_t c_flags, int isdir)
1207 {
1208 	uint16_t z_flags = 0;
1209 
1210 	if (c_flags & SUCCESSFUL_ACCESS_ACE_FLAG)
1211 		z_flags |= ACE_SUCCESSFUL_ACCESS_ACE_FLAG;
1212 
1213 	if (c_flags & FAILED_ACCESS_ACE_FLAG)
1214 		z_flags |= ACE_FAILED_ACCESS_ACE_FLAG;
1215 
1216 	if (c_flags & INHERITED_ACE)
1217 		z_flags |= ACE_INHERITED_ACE;
1218 
1219 	/*
1220 	 * ZFS doesn't like any inheritance flags to be set on a
1221 	 * file's ACE, only directories. Windows doesn't care.
1222 	 */
1223 	if (isdir)
1224 		z_flags |= (c_flags & ACE_INHERIT_FLAGS);
1225 
1226 	return (z_flags);
1227 }
1228 
1229 static uint8_t
1230 smb_ace_flags_fromzfs(uint16_t z_flags)
1231 {
1232 	uint8_t c_flags;
1233 
1234 	c_flags = z_flags & ACE_INHERIT_FLAGS;
1235 
1236 	if (z_flags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)
1237 		c_flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
1238 
1239 	if (z_flags & ACE_FAILED_ACCESS_ACE_FLAG)
1240 		c_flags |= FAILED_ACCESS_ACE_FLAG;
1241 
1242 	if (z_flags & ACE_INHERITED_ACE)
1243 		c_flags |= INHERITED_ACE;
1244 
1245 	return (c_flags);
1246 }
1247 
1248 /*
1249  * This is generic (ACL version 2) vs. object-specific
1250  * (ACL version 4) ACE types.
1251  */
1252 int
1253 smb_ace_is_generic(int type)
1254 {
1255 	switch (type) {
1256 	case ACE_ACCESS_ALLOWED_ACE_TYPE:
1257 	case ACE_ACCESS_DENIED_ACE_TYPE:
1258 	case ACE_SYSTEM_AUDIT_ACE_TYPE:
1259 	case ACE_SYSTEM_ALARM_ACE_TYPE:
1260 	case ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
1261 	case ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE:
1262 	case ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
1263 	case ACE_SYSTEM_ALARM_CALLBACK_ACE_TYPE:
1264 		return (1);
1265 
1266 	default:
1267 		break;
1268 	}
1269 
1270 	return (0);
1271 }
1272 
1273 int
1274 smb_ace_is_access(int type)
1275 {
1276 	switch (type) {
1277 	case ACE_ACCESS_ALLOWED_ACE_TYPE:
1278 	case ACE_ACCESS_DENIED_ACE_TYPE:
1279 	case ACE_ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
1280 	case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
1281 	case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
1282 	case ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
1283 	case ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE:
1284 	case ACE_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
1285 	case ACE_ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
1286 		return (1);
1287 
1288 	default:
1289 		break;
1290 	}
1291 
1292 	return (0);
1293 }
1294 
1295 int
1296 smb_ace_is_audit(int type)
1297 {
1298 	switch (type) {
1299 	case ACE_SYSTEM_AUDIT_ACE_TYPE:
1300 	case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
1301 	case ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
1302 	case ACE_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
1303 		return (1);
1304 
1305 	default:
1306 		break;
1307 	}
1308 
1309 	return (0);
1310 }
1311