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