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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
28 #include <sys/errno.h>
30 #include <sys/t_lock.h>
31 #include <sys/ksynch.h>
34 #include <sys/vnode.h>
36 #include <sys/systm.h>
40 #include <sys/fs/ufs_inode.h>
41 #include <sys/fs/ufs_acl.h>
42 #include <sys/fs/ufs_quota.h>
43 #include <sys/sysmacros.h>
44 #include <sys/debug.h>
45 #include <sys/policy.h>
48 static int si_signature(si_t
*);
49 static int si_cachei_get(struct inode
*, si_t
**);
50 static int si_cachea_get(struct inode
*, si_t
*, si_t
**);
51 static int si_cmp(si_t
*, si_t
*);
52 static void si_cache_put(si_t
*);
53 void si_cache_del(si_t
*, int);
54 void si_cache_init(void);
56 static void ufs_si_free_mem(si_t
*);
57 static int ufs_si_store(struct inode
*, si_t
*, int, cred_t
*);
58 static si_t
*ufs_acl_cp(si_t
*);
59 static int ufs_sectobuf(si_t
*, caddr_t
*, size_t *);
60 static int acl_count(ufs_ic_acl_t
*);
61 static int acl_validate(aclent_t
*, int, int);
62 static int vsecattr2aclentry(vsecattr_t
*, si_t
**);
63 static int aclentry2vsecattr(si_t
*, vsecattr_t
*);
65 krwlock_t si_cache_lock
; /* Protects si_cache */
66 int si_cachecnt
= 64; /* # buckets in si_cache[a|i] */
67 si_t
**si_cachea
; /* The 'by acl' cache chains */
68 si_t
**si_cachei
; /* The 'by inode' cache chains */
70 long si_cachemiss
= 0;
72 #define SI_HASH(S) ((int)(S) & (si_cachecnt - 1))
75 * Store the new acls in aclp. Attempts to make things atomic.
76 * Search the acl cache for an identical sp and, if found, attach
77 * the cache'd acl to ip. If the acl is new (not in the cache),
78 * add it to the cache, then attach it to ip. Last, remove and
79 * decrement the reference count of any prior acl list attached
83 * ip - Ptr to inode to receive the acl list
84 * sp - Ptr to in-core acl structure to attach to the inode.
85 * puship - 0 do not push the object inode(ip) 1 push the ip
86 * cr - Ptr to credentials
88 * Returns: 0 - Success
92 ufs_si_store(struct inode
*ip
, si_t
*sp
, int puship
, cred_t
*cr
)
108 struct ufsvfs
*ufsvfsp
= ip
->i_ufsvfs
;
109 struct fs
*fs
= ufsvfsp
->vfs_fs
;
111 ASSERT(RW_WRITE_HELD(&ip
->i_contents
));
112 ASSERT(ip
->i_ufs_acl
!= sp
);
114 if (!CHECK_ACL_ALLOWED(ip
->i_mode
& IFMT
))
118 * if there are only the three owner/group/other then do not
119 * create a shadow inode. If there is already a shadow with
120 * the file, remove it.
128 sp
->dclass
.acl_ismask
== 0 &&
132 err
= ufs_si_free(ip
->i_ufs_acl
, ITOV(ip
)->v_vfsp
, cr
);
133 ip
->i_ufs_acl
= NULL
;
135 ip
->i_flag
|= IMOD
| IACC
;
136 ip
->i_mode
= (ip
->i_smode
& ~0777) |
137 ((sp
->aowner
->acl_ic_perm
& 07) << 6) |
139 (sp
->aother
->acl_ic_perm
& 07);
140 TRANS_INODE(ip
->i_ufsvfs
, ip
);
149 * Check cache. If in cache, use existing shadow inode.
150 * Increment the shadow link count, then attach to the
151 * cached ufs_acl_entry struct, and increment it's reference
152 * count. Then discard the passed-in ufs_acl_entry and
155 if (si_cachea_get(ip
, sp
, &csp
) == 0) {
156 ASSERT(RW_WRITE_HELD(&csp
->s_lock
));
157 if (ip
->i_ufs_acl
== csp
) {
158 rw_exit(&csp
->s_lock
);
159 (void) ufs_si_free_mem(sp
);
162 vfsp
= ITOV(ip
)->v_vfsp
;
163 ASSERT(csp
->s_shadow
<= INT_MAX
);
164 shadow
= (int)csp
->s_shadow
;
166 * We can't call ufs_iget while holding the csp locked,
167 * because we might deadlock. So we drop the
168 * lock on csp, then go search the si_cache again
169 * to see if the csp is still there.
171 rw_exit(&csp
->s_lock
);
172 if ((err
= ufs_iget(vfsp
, shadow
, &sip
, cr
)) != 0) {
173 (void) ufs_si_free_mem(sp
);
176 rw_enter(&sip
->i_contents
, RW_WRITER
);
177 if ((sip
->i_mode
& IFMT
) != IFSHAD
|| sip
->i_nlink
<= 0) {
178 rw_exit(&sip
->i_contents
);
182 /* Get the csp again */
183 if (si_cachea_get(ip
, sp
, &csp
) != 0) {
184 rw_exit(&sip
->i_contents
);
188 ASSERT(RW_WRITE_HELD(&csp
->s_lock
));
189 /* See if we got the right shadow */
190 if (csp
->s_shadow
!= shadow
) {
191 rw_exit(&csp
->s_lock
);
192 rw_exit(&sip
->i_contents
);
196 ASSERT(RW_WRITE_HELD(&sip
->i_contents
));
197 ASSERT(sip
->i_dquot
== 0);
198 /* Increment link count */
199 ASSERT(sip
->i_nlink
> 0);
201 TRANS_INODE(ufsvfsp
, sip
);
202 csp
->s_use
= sip
->i_nlink
;
204 ASSERT(sp
->s_ref
>= 0 && sp
->s_ref
<= sp
->s_use
);
205 sip
->i_flag
|= ICHG
| IMOD
;
209 * Always release s_lock before both releasing i_contents
210 * and calling VN_RELE.
212 rw_exit(&csp
->s_lock
);
213 rw_exit(&sip
->i_contents
);
215 (void) ufs_si_free_mem(sp
);
221 /* Alloc a shadow inode and fill it in */
222 err
= ufs_ialloc(ip
, ip
->i_number
, (mode_t
)IFSHAD
, &sip
, cr
);
224 (void) ufs_si_free_mem(sp
);
227 rw_enter(&sip
->i_contents
, RW_WRITER
);
228 sip
->i_flag
|= IACC
| IUPD
| ICHG
;
230 sip
->i_mode
= (o_mode_t
)IFSHAD
;
231 ITOV(sip
)->v_type
= VREG
;
232 ufs_reset_vnode(ITOV(sip
));
234 sip
->i_uid
= crgetuid(cr
);
235 sip
->i_suid
= (ulong_t
)sip
->i_uid
> (ulong_t
)USHRT_MAX
?
236 UID_LONG
: sip
->i_uid
;
237 sip
->i_gid
= crgetgid(cr
);
238 sip
->i_sgid
= (ulong_t
)sip
->i_gid
> (ulong_t
)USHRT_MAX
?
239 GID_LONG
: sip
->i_gid
;
241 TRANS_INODE(ufsvfsp
, sip
);
242 sip
->i_ufs_acl
= NULL
;
243 ASSERT(sip
->i_size
== 0);
245 sp
->s_shadow
= sip
->i_number
;
247 if ((err
= ufs_sectobuf(sp
, &acldata
, &acldatalen
)) != 0)
252 * We don't actually care about the residual count upon failure,
253 * but giving ufs_rdwri() the pointer means it won't translate
254 * all failures to EIO. Our caller needs to know when ENOSPC
258 if (((err
= ufs_rdwri(UIO_WRITE
, FWRITE
|FSYNC
, sip
, acldata
,
259 acldatalen
, (offset_t
)0, UIO_SYSSPACE
, &resid
, cr
)) != 0) ||
261 kmem_free(acldata
, acldatalen
);
262 if ((resid
!= 0) && (err
== 0))
267 offset
+= acldatalen
;
268 if ((acldatalen
+ fs
->fs_bsize
) > ufsvfsp
->vfs_maxacl
)
269 ufsvfsp
->vfs_maxacl
= acldatalen
+ fs
->fs_bsize
;
271 kmem_free(acldata
, acldatalen
);
272 /* Sync & free the shadow inode */
274 rw_exit(&sip
->i_contents
);
277 /* We're committed to using this sp */
281 /* Now put the new acl stuff in the cache */
282 /* XXX Might make a duplicate */
287 /* Now switch the parent inode to use the new shadow inode */
288 ASSERT(RW_WRITE_HELD(&ip
->i_contents
));
289 rw_enter(&sp
->s_lock
, RW_READER
);
290 oldsp
= ip
->i_ufs_acl
;
291 oldshadow
= ip
->i_shadow
;
293 ASSERT(sp
->s_shadow
<= INT_MAX
);
294 ip
->i_shadow
= (int32_t)sp
->s_shadow
;
296 ASSERT(oldshadow
!= ip
->i_number
);
297 ASSERT(ip
->i_number
!= ip
->i_shadow
);
299 * Change the mode bits to follow the acl list
301 * NOTE: a directory is not required to have a "regular" acl
302 * bug id's 1238908, 1257173, 1263171 and 1263188
304 * but if a "regular" acl is present, it must contain
305 * an "owner", "group", and "other" acl
307 * If an ACL mask exists, the effective group rights are
308 * set to the mask. Otherwise, the effective group rights
309 * are set to the object group bits.
311 if (sp
->aowner
) { /* Owner */
312 ip
->i_mode
&= ~0700; /* clear Owner */
313 ip
->i_mode
|= (sp
->aowner
->acl_ic_perm
& 07) << 6;
314 ip
->i_uid
= sp
->aowner
->acl_ic_who
;
317 if (sp
->agroup
) { /* Group */
318 ip
->i_mode
&= ~0070; /* clear Group */
319 ip
->i_mode
|= MASK2MODE(sp
); /* apply mask */
320 ip
->i_gid
= sp
->agroup
->acl_ic_who
;
323 if (sp
->aother
) { /* Other */
324 ip
->i_mode
&= ~0007; /* clear Other */
325 ip
->i_mode
|= (sp
->aother
->acl_ic_perm
& 07);
328 if (sp
->aclass
.acl_ismask
)
329 ip
->i_mode
= (ip
->i_mode
& ~070) |
330 (((sp
->aclass
.acl_maskbits
& 07) << 3) &
333 TRANS_INODE(ufsvfsp
, ip
);
334 rw_exit(&sp
->s_lock
);
338 * when creating a file there is no need to push the inode, it
345 * Decrement link count on the old shadow inode,
346 * and decrement reference count on the old aclp,
349 /* Get the shadow inode */
350 ASSERT(RW_WRITE_HELD(&ip
->i_contents
));
351 vfsp
= ITOV(ip
)->v_vfsp
;
352 if ((err
= ufs_iget_alloced(vfsp
, oldshadow
, &sip
, cr
)) != 0) {
355 /* Decrement link count */
356 rw_enter(&sip
->i_contents
, RW_WRITER
);
358 rw_enter(&oldsp
->s_lock
, RW_WRITER
);
359 ASSERT(sip
->i_dquot
== 0);
360 ASSERT(sip
->i_nlink
> 0);
361 usecnt
= --sip
->i_nlink
;
363 TRANS_INODE(ufsvfsp
, sip
);
364 sip
->i_flag
|= ICHG
| IMOD
;
368 oldsp
->s_use
= usecnt
;
369 refcnt
= --oldsp
->s_ref
;
370 signature
= oldsp
->s_signature
;
372 * Always release s_lock before both releasing
373 * i_contents and calling VN_RELE.
375 rw_exit(&oldsp
->s_lock
);
377 rw_exit(&sip
->i_contents
);
379 if (oldsp
&& (refcnt
== 0))
380 si_cache_del(oldsp
, signature
);
385 /* Throw the newly alloc'd inode away */
388 TRANS_INODE(ufsvfsp
, sip
);
390 rw_exit(&sip
->i_contents
);
392 ASSERT(!sp
->s_use
&& !sp
->s_ref
&& !(sp
->s_flags
& SI_CACHED
));
393 (void) ufs_si_free_mem(sp
);
398 * Load the acls for inode ip either from disk (adding to the cache),
399 * or search the cache and attach the cache'd acl list to the ip.
400 * In either case, maintain the proper reference count on the cached entry.
403 * ip - Ptr to the inode which needs the acl list loaded
404 * cr - Ptr to credentials
406 * Returns: 0 - Success
410 ufs_si_load(struct inode
*ip
, cred_t
*cr
)
420 vsecattr_t vsecattr
= {
428 caddr_t acldata
= NULL
;
435 struct ufsvfs
*ufsvfsp
= ip
->i_ufsvfs
;
436 struct fs
*fs
= ufsvfsp
->vfs_fs
;
439 ASSERT(RW_WRITE_HELD(&ip
->i_contents
));
440 ASSERT(ip
->i_shadow
&& ip
->i_ufs_acl
== NULL
);
441 ASSERT((ip
->i_mode
& IFMT
) != IFSHAD
);
443 if (!CHECK_ACL_ALLOWED(ip
->i_mode
& IFMT
))
446 if (ip
->i_shadow
== ip
->i_number
)
449 maxino
= (ino_t
)(ITOF(ip
)->fs_ncg
* ITOF(ip
)->fs_ipg
);
450 if (ip
->i_shadow
< UFSROOTINO
|| ip
->i_shadow
> maxino
)
454 * XXX Check cache. If in cache, link to it and increment
455 * the reference count, then return.
457 if (si_cachei_get(ip
, &sp
) == 0) {
458 ASSERT(RW_WRITE_HELD(&sp
->s_lock
));
461 ASSERT(sp
->s_ref
>= 0 && sp
->s_ref
<= sp
->s_use
);
462 rw_exit(&sp
->s_lock
);
467 /* Get the shadow inode */
468 vfsp
= ITOV(ip
)->v_vfsp
;
469 shadow
= ip
->i_shadow
;
470 if ((err
= ufs_iget_alloced(vfsp
, shadow
, &sip
, cr
)) != 0) {
473 rw_enter(&sip
->i_contents
, RW_WRITER
);
475 if ((sip
->i_mode
& IFMT
) != IFSHAD
) {
476 rw_exit(&sip
->i_contents
);
481 ASSERT(sip
->i_dquot
== 0);
482 usecnt
= sip
->i_nlink
;
483 if ((!ULOCKFS_IS_NOIACC(&ufsvfsp
->vfs_ulockfs
)) &&
484 (!(sip
)->i_ufsvfs
->vfs_noatime
)) {
487 rw_downgrade(&sip
->i_contents
);
489 ASSERT(sip
->i_size
<= MAXOFF_T
);
490 /* Read the acl's and other stuff from disk */
491 acldata
= kmem_zalloc((size_t)sip
->i_size
, KM_SLEEP
);
492 acldatalen
= sip
->i_size
;
494 err
= ufs_rdwri(UIO_READ
, FREAD
, sip
, acldata
, acldatalen
, (offset_t
)0,
495 UIO_SYSSPACE
, (int *)0, cr
);
497 rw_exit(&sip
->i_contents
);
503 * Convert from disk format
504 * Result is a vsecattr struct which we then convert to the
507 bzero((caddr_t
)&vsecattr
, sizeof (vsecattr_t
));
508 for (fsdp
= (ufs_fsd_t
*)acldata
;
509 fsdp
< (ufs_fsd_t
*)(acldata
+ acldatalen
);
510 fsdp
= (ufs_fsd_t
*)((caddr_t
)fsdp
+
511 FSD_RECSZ(fsdp
, fsdp
->fsd_size
))) {
512 if (fsdp
->fsd_size
<= 0)
514 switch (fsdp
->fsd_type
) {
516 numacls
= vsecattr
.vsa_aclcnt
=
517 (int)((fsdp
->fsd_size
- 2 * sizeof (int)) /
519 aclp
= vsecattr
.vsa_aclentp
=
520 kmem_zalloc(numacls
* sizeof (aclent_t
), KM_SLEEP
);
521 for (ufsaclp
= (ufs_acl_t
*)fsdp
->fsd_data
;
522 numacls
; ufsaclp
++) {
523 aclp
->a_type
= ufsaclp
->acl_tag
;
524 aclp
->a_id
= ufsaclp
->acl_who
;
525 aclp
->a_perm
= ufsaclp
->acl_perm
;
531 numacls
= vsecattr
.vsa_dfaclcnt
=
532 (int)((fsdp
->fsd_size
- 2 * sizeof (int)) /
534 aclp
= vsecattr
.vsa_dfaclentp
=
535 kmem_zalloc(numacls
* sizeof (aclent_t
), KM_SLEEP
);
536 for (ufsaclp
= (ufs_acl_t
*)fsdp
->fsd_data
;
537 numacls
; ufsaclp
++) {
538 aclp
->a_type
= ufsaclp
->acl_tag
;
539 aclp
->a_id
= ufsaclp
->acl_who
;
540 aclp
->a_perm
= ufsaclp
->acl_perm
;
548 if (vsecattr
.vsa_aclentp
) {
549 ksort((caddr_t
)vsecattr
.vsa_aclentp
, vsecattr
.vsa_aclcnt
,
550 sizeof (aclent_t
), cmp2acls
);
551 if ((err
= acl_validate(vsecattr
.vsa_aclentp
,
552 vsecattr
.vsa_aclcnt
, ACL_CHECK
)) != 0) {
556 if (vsecattr
.vsa_dfaclentp
) {
557 ksort((caddr_t
)vsecattr
.vsa_dfaclentp
, vsecattr
.vsa_dfaclcnt
,
558 sizeof (aclent_t
), cmp2acls
);
559 if ((err
= acl_validate(vsecattr
.vsa_dfaclentp
,
560 vsecattr
.vsa_dfaclcnt
, DEF_ACL_CHECK
)) != 0) {
565 /* ignore shadow inodes without ACLs */
566 if (!vsecattr
.vsa_aclentp
&& !vsecattr
.vsa_dfaclentp
) {
571 /* Convert from vsecattr struct to ufs_acl_entry struct */
572 if ((err
= vsecattr2aclentry(&vsecattr
, &sp
)) != 0) {
576 /* There aren't filled in by vsecattr2aclentry */
577 sp
->s_shadow
= ip
->i_shadow
;
578 sp
->s_dev
= ip
->i_dev
;
581 ASSERT(sp
->s_ref
>= 0 && sp
->s_ref
<= sp
->s_use
);
583 /* XXX Might make a duplicate */
586 /* Signal anyone waiting on this shadow to be loaded */
590 if ((acldatalen
+ fs
->fs_bsize
) > ufsvfsp
->vfs_maxacl
)
591 ufsvfsp
->vfs_maxacl
= acldatalen
+ fs
->fs_bsize
;
594 * Common exit point. Mark shadow inode as ISTALE
595 * if we detect an internal inconsistency, to
596 * prevent stray inodes appearing in the cache.
599 rw_enter(&sip
->i_contents
, RW_READER
);
600 mutex_enter(&sip
->i_tlock
);
601 sip
->i_flag
|= ISTALE
;
602 mutex_exit(&sip
->i_tlock
);
603 rw_exit(&sip
->i_contents
);
608 * Cleanup of data structures allocated
612 kmem_free(acldata
, acldatalen
);
614 if (vsecattr
.vsa_aclentp
)
615 kmem_free(vsecattr
.vsa_aclentp
,
616 vsecattr
.vsa_aclcnt
* sizeof (aclent_t
));
617 if (vsecattr
.vsa_dfaclentp
)
618 kmem_free(vsecattr
.vsa_dfaclentp
,
619 vsecattr
.vsa_dfaclcnt
* sizeof (aclent_t
));
624 * Check the inode's ACL's to see if this mode of access is
625 * allowed; return 0 if allowed, EACCES if not.
627 * We follow the procedure defined in Sec. 3.3.5, ACL Access
628 * Check Algorithm, of the POSIX 1003.6 Draft Standard.
631 ufs_acl_access(struct inode
*ip
, int mode
, cred_t
*cr
)
634 * mode mode of access read, write, execute/examine
639 int ismask
, mask
= 0;
643 uid_t uid
= crgetuid(cr
);
646 ASSERT(ip
->i_ufs_acl
!= NULL
);
647 ASSERT(RW_LOCK_HELD(&ip
->i_contents
));
651 ismask
= sp
->aclass
.acl_ismask
?
652 sp
->aclass
.acl_ismask
: NULL
;
655 mask
= sp
->aclass
.acl_maskbits
;
660 * (1) If user owns the file, obey user mode bits
662 owner
= sp
->aowner
->acl_ic_who
;
664 return (MODE_CHECK(owner
, mode
, (sp
->aowner
->acl_ic_perm
<< 6),
669 * (2) Obey any matching ACL_USER entry
672 for (acl
= sp
->ausers
; acl
!= NULL
; acl
= acl
->acl_ic_next
) {
673 if (acl
->acl_ic_who
== uid
) {
674 return (MODE_CHECK(owner
, mode
,
675 (mask
& acl
->acl_ic_perm
) << 6, cr
, ip
));
680 * (3) If user belongs to file's group, obey group mode bits
681 * if no ACL mask is defined; if there is an ACL mask, we look
682 * at both the group mode bits and any ACL_GROUP entries.
684 if (groupmember((uid_t
)sp
->agroup
->acl_ic_who
, cr
)) {
686 gperm
= (sp
->agroup
->acl_ic_perm
);
688 return (MODE_CHECK(owner
, mode
, (gperm
<< 6), cr
, ip
));
692 * (4) Accumulate the permissions in matching ACL_GROUP entries
695 for (acl
= sp
->agroups
; acl
!= NULL
; acl
= acl
->acl_ic_next
)
697 if (groupmember(acl
->acl_ic_who
, cr
)) {
699 gperm
|= acl
->acl_ic_perm
;
704 return (MODE_CHECK(owner
, mode
, ((gperm
& mask
) << 6), cr
, ip
));
707 * (5) Finally, use the "other" mode bits
709 return (MODE_CHECK(owner
, mode
, sp
->aother
->acl_ic_perm
<< 6, cr
, ip
));
714 ufs_acl_get(struct inode
*ip
, vsecattr_t
*vsap
, int flag
, cred_t
*cr
)
718 ASSERT(RW_LOCK_HELD(&ip
->i_contents
));
720 /* XXX Range check, sanity check, shadow check */
721 /* If an ACL is present, get the data from the shadow inode info */
723 return (aclentry2vsecattr(ip
->i_ufs_acl
, vsap
));
726 * If no ACLs are present, fabricate one from the mode bits.
727 * This code is almost identical to fs_fab_acl(), but we
728 * already have the mode bits handy, so we'll avoid going
729 * through VOP_GETATTR() again.
732 vsap
->vsa_aclcnt
= 0;
733 vsap
->vsa_aclentp
= NULL
;
734 vsap
->vsa_dfaclcnt
= 0; /* Default ACLs are not fabricated */
735 vsap
->vsa_dfaclentp
= NULL
;
737 if (vsap
->vsa_mask
& (VSA_ACLCNT
| VSA_ACL
))
738 vsap
->vsa_aclcnt
= 4; /* USER, GROUP, OTHER, and CLASS */
740 if (vsap
->vsa_mask
& VSA_ACL
) {
741 vsap
->vsa_aclentp
= kmem_zalloc(4 * sizeof (aclent_t
),
743 if (vsap
->vsa_aclentp
== NULL
)
745 aclentp
= vsap
->vsa_aclentp
;
748 aclentp
->a_type
= USER_OBJ
;
749 aclentp
->a_perm
= ((ushort_t
)(ip
->i_mode
& 0700)) >> 6;
750 aclentp
->a_id
= ip
->i_uid
; /* Really undefined */
754 aclentp
->a_type
= GROUP_OBJ
;
755 aclentp
->a_perm
= ((ushort_t
)(ip
->i_mode
& 0070)) >> 3;
756 aclentp
->a_id
= ip
->i_gid
; /* Really undefined */
760 aclentp
->a_type
= OTHER_OBJ
;
761 aclentp
->a_perm
= ip
->i_mode
& 0007;
762 aclentp
->a_id
= 0; /* Really undefined */
766 aclentp
->a_type
= CLASS_OBJ
;
767 aclentp
->a_perm
= ((ushort_t
)(ip
->i_mode
& 0070)) >> 3;
768 aclentp
->a_id
= 0; /* Really undefined */
769 ksort((caddr_t
)vsap
->vsa_aclentp
, vsap
->vsa_aclcnt
,
770 sizeof (aclent_t
), cmp2acls
);
778 ufs_acl_set(struct inode
*ip
, vsecattr_t
*vsap
, int flag
, cred_t
*cr
)
783 ASSERT(RW_WRITE_HELD(&ip
->i_contents
));
785 if (!CHECK_ACL_ALLOWED(ip
->i_mode
& IFMT
))
789 * only the owner of the file or privileged users can change the ACLs
791 if (secpolicy_vnode_setdac(cr
, ip
->i_uid
) != 0)
794 /* Convert from vsecattr struct to ufs_acl_entry struct */
795 if ((err
= vsecattr2aclentry(vsap
, &sp
)) != 0)
797 sp
->s_dev
= ip
->i_dev
;
800 * Make the user & group objs in the acl list follow what's
804 if (vsap
->vsa_mask
== VSA_ACL
) {
812 sp
->aowner
->acl_ic_who
= ip
->i_uid
;
814 sp
->agroup
->acl_ic_who
= ip
->i_gid
;
817 * Write and cache the new acl list
819 err
= ufs_si_store(ip
, sp
, 1, cr
);
825 * XXX Scan sorted array of acl's, checking for:
826 * 1) Any duplicate/conflicting entries (same type and id)
827 * 2) More than 1 of USER_OBJ, GROUP_OBJ, OTHER_OBJ, CLASS_OBJ
828 * 3) More than 1 of DEF_USER_OBJ, DEF_GROUP_OBJ, DEF_OTHER_OBJ, DEF_CLASS_OBJ
831 * aclentp - ptr to sorted list of acl entries.
832 * nentries - # acl entries on the list
833 * flag - Bitmap (ACL_CHECK and/or DEF_ACL_CHECK) indicating whether the
834 * list contains regular acls, default acls, or both.
836 * Returns: 0 - Success
837 * EINVAL - Invalid list (dups or multiple entries of type USER_OBJ, etc)
840 acl_validate(aclent_t
*aclentp
, int nentries
, int flag
)
847 int ndef_user_objs
= 0;
848 int ndef_group_objs
= 0;
849 int ndef_other_objs
= 0;
850 int ndef_class_objs
= 0;
857 /* Null list or list of one */
864 for (i
= 1; i
< nentries
; i
++) {
865 if (((aclentp
[i
- 1].a_type
== aclentp
[i
].a_type
) &&
866 (aclentp
[i
- 1].a_id
== aclentp
[i
].a_id
)) ||
867 (aclentp
[i
- 1].a_perm
> 07)) {
872 if (flag
== 0 || (flag
!= ACL_CHECK
&& flag
!= DEF_ACL_CHECK
))
876 for (i
= 0; i
< nentries
; i
++) {
877 switch (aclentp
[i
].a_type
) {
878 case USER_OBJ
: /* Owner */
881 case GROUP_OBJ
: /* Group */
884 case OTHER_OBJ
: /* Other */
887 case CLASS_OBJ
: /* Mask */
890 case DEF_USER_OBJ
: /* Default Owner */
893 case DEF_GROUP_OBJ
: /* Default Group */
896 case DEF_OTHER_OBJ
: /* Default Other */
899 case DEF_CLASS_OBJ
: /* Default Mask */
902 case USER
: /* Users */
905 case GROUP
: /* Groups */
908 case DEF_USER
: /* Default Users */
911 case DEF_GROUP
: /* Default Groups */
914 default: /* Unknown type */
920 * For normal acl's, we require there be one (and only one)
921 * USER_OBJ, GROUP_OBJ and OTHER_OBJ. There is either zero
924 if (flag
& ACL_CHECK
) {
925 if (nuser_objs
!= 1 || ngroup_objs
!= 1 ||
926 nother_objs
!= 1 || nclass_objs
> 1) {
930 * If there are ANY group acls, there MUST be a
931 * class_obj(mask) acl (1003.6/D12 p. 29 lines 75-80).
933 if (ngroups
&& !nclass_objs
) {
936 if (nuser_objs
+ ngroup_objs
+ nother_objs
+ nclass_objs
+
937 ngroups
+ nusers
> MAX_ACL_ENTRIES
)
942 * For default acl's, we require that there be either one (and only one)
943 * DEF_USER_OBJ, DEF_GROUP_OBJ and DEF_OTHER_OBJ
944 * or there be none of them.
946 if (flag
& DEF_ACL_CHECK
) {
947 if (ndef_other_objs
> 1 || ndef_user_objs
> 1 ||
948 ndef_group_objs
> 1 || ndef_class_objs
> 1) {
952 numdefs
= ndef_other_objs
+ ndef_user_objs
+ ndef_group_objs
;
954 if (numdefs
!= 0 && numdefs
!= 3) {
958 * If there are ANY def_group acls, there MUST be a
959 * def_class_obj(mask) acl (1003.6/D12 P. 29 lines 75-80).
960 * XXX(jimh) This is inferred.
962 if (ndef_groups
&& !ndef_class_objs
) {
965 if ((ndef_users
|| ndef_groups
) &&
966 ((numdefs
!= 3) && !ndef_class_objs
)) {
969 if (ndef_user_objs
+ ndef_group_objs
+ ndef_other_objs
+
970 ndef_class_objs
+ ndef_users
+ ndef_groups
>
978 formacl(ufs_ic_acl_t
**aclpp
, aclent_t
*aclentp
)
982 uaclp
= kmem_alloc(sizeof (ufs_ic_acl_t
), KM_SLEEP
);
983 uaclp
->acl_ic_perm
= aclentp
->a_perm
;
984 uaclp
->acl_ic_who
= aclentp
->a_id
;
985 uaclp
->acl_ic_next
= *aclpp
;
991 * XXX - Make more efficient
992 * Convert from the vsecattr struct, used by the VOP interface, to
993 * the ufs_acl_entry struct used for in-core storage of acl's.
996 * vsap - Ptr to array of security attributes.
997 * spp - Ptr to ptr to si struct for the results
999 * Returns: 0 - Success
1003 vsecattr2aclentry(vsecattr_t
*vsap
, si_t
**spp
)
1005 aclent_t
*aclentp
, *aclp
;
1010 /* Sort & validate the lists on the vsap */
1011 ksort((caddr_t
)vsap
->vsa_aclentp
, vsap
->vsa_aclcnt
,
1012 sizeof (aclent_t
), cmp2acls
);
1013 ksort((caddr_t
)vsap
->vsa_dfaclentp
, vsap
->vsa_dfaclcnt
,
1014 sizeof (aclent_t
), cmp2acls
);
1015 if ((err
= acl_validate(vsap
->vsa_aclentp
,
1016 vsap
->vsa_aclcnt
, ACL_CHECK
)) != 0)
1018 if ((err
= acl_validate(vsap
->vsa_dfaclentp
,
1019 vsap
->vsa_dfaclcnt
, DEF_ACL_CHECK
)) != 0)
1022 /* Create new si struct and hang acl's off it */
1023 sp
= kmem_zalloc(sizeof (si_t
), KM_SLEEP
);
1024 rw_init(&sp
->s_lock
, NULL
, RW_DEFAULT
, NULL
);
1026 /* Process acl list */
1027 aclp
= (aclent_t
*)vsap
->vsa_aclentp
;
1028 aclentp
= aclp
+ vsap
->vsa_aclcnt
- 1;
1029 for (i
= 0; i
< vsap
->vsa_aclcnt
; i
++) {
1030 switch (aclentp
->a_type
) {
1031 case USER_OBJ
: /* Owner */
1032 if (err
= formacl(&sp
->aowner
, aclentp
))
1035 case GROUP_OBJ
: /* Group */
1036 if (err
= formacl(&sp
->agroup
, aclentp
))
1039 case OTHER_OBJ
: /* Other */
1040 if (err
= formacl(&sp
->aother
, aclentp
))
1044 if (err
= formacl(&sp
->ausers
, aclentp
))
1047 case CLASS_OBJ
: /* Mask */
1048 sp
->aclass
.acl_ismask
= 1;
1049 sp
->aclass
.acl_maskbits
= aclentp
->a_perm
;
1052 if (err
= formacl(&sp
->agroups
, aclentp
))
1061 /* Process default acl list */
1062 aclp
= (aclent_t
*)vsap
->vsa_dfaclentp
;
1063 aclentp
= aclp
+ vsap
->vsa_dfaclcnt
- 1;
1064 for (i
= 0; i
< vsap
->vsa_dfaclcnt
; i
++) {
1065 switch (aclentp
->a_type
) {
1066 case DEF_USER_OBJ
: /* Default Owner */
1067 if (err
= formacl(&sp
->downer
, aclentp
))
1070 case DEF_GROUP_OBJ
: /* Default Group */
1071 if (err
= formacl(&sp
->dgroup
, aclentp
))
1074 case DEF_OTHER_OBJ
: /* Default Other */
1075 if (err
= formacl(&sp
->dother
, aclentp
))
1079 if (err
= formacl(&sp
->dusers
, aclentp
))
1082 case DEF_CLASS_OBJ
: /* Default Mask */
1083 sp
->dclass
.acl_ismask
= 1;
1084 sp
->dclass
.acl_maskbits
= aclentp
->a_perm
;
1087 if (err
= formacl(&sp
->dgroups
, aclentp
))
1099 ufs_si_free_mem(sp
);
1104 formvsec(int obj_type
, ufs_ic_acl_t
*aclp
, aclent_t
**aclentpp
)
1106 for (; aclp
; aclp
= aclp
->acl_ic_next
) {
1107 (*aclentpp
)->a_type
= obj_type
;
1108 (*aclentpp
)->a_perm
= aclp
->acl_ic_perm
;
1109 (*aclentpp
)->a_id
= aclp
->acl_ic_who
;
1115 * XXX - Make more efficient
1116 * Convert from the ufs_acl_entry struct used for in-core storage of acl's
1117 * to the vsecattr struct, used by the VOP interface.
1120 * sp - Ptr to si struct with the acls
1121 * vsap - Ptr to a vsecattr struct which will take the results.
1123 * Returns: 0 - Success
1124 * N - From errno table
1127 aclentry2vsecattr(si_t
*sp
, vsecattr_t
*vsap
)
1133 vsap
->vsa_aclentp
= vsap
->vsa_dfaclentp
= NULL
;
1135 numacls
= acl_count(sp
->aowner
) +
1136 acl_count(sp
->agroup
) +
1137 acl_count(sp
->aother
) +
1138 acl_count(sp
->ausers
) +
1139 acl_count(sp
->agroups
);
1140 if (sp
->aclass
.acl_ismask
)
1143 if (vsap
->vsa_mask
& (VSA_ACLCNT
| VSA_ACL
))
1144 vsap
->vsa_aclcnt
= numacls
;
1149 if (vsap
->vsa_mask
& VSA_ACL
) {
1150 vsap
->vsa_aclentp
= kmem_zalloc(numacls
* sizeof (aclent_t
),
1152 aclentp
= vsap
->vsa_aclentp
;
1154 formvsec(USER_OBJ
, sp
->aowner
, &aclentp
);
1155 formvsec(USER
, sp
->ausers
, &aclentp
);
1156 formvsec(GROUP_OBJ
, sp
->agroup
, &aclentp
);
1157 formvsec(GROUP
, sp
->agroups
, &aclentp
);
1158 formvsec(OTHER_OBJ
, sp
->aother
, &aclentp
);
1160 if (sp
->aclass
.acl_ismask
) {
1161 aclentp
->a_type
= CLASS_OBJ
; /* Mask */
1162 aclentp
->a_perm
= sp
->aclass
.acl_maskbits
;
1167 /* Sort the acl list */
1168 ksort((caddr_t
)vsap
->vsa_aclentp
, vsap
->vsa_aclcnt
,
1169 sizeof (aclent_t
), cmp2acls
);
1170 /* Check the acl list */
1171 if ((err
= acl_validate(vsap
->vsa_aclentp
,
1172 vsap
->vsa_aclcnt
, ACL_CHECK
)) != 0) {
1173 kmem_free(vsap
->vsa_aclentp
,
1174 numacls
* sizeof (aclent_t
));
1175 vsap
->vsa_aclentp
= NULL
;
1181 /* Process Defaults */
1183 numacls
= acl_count(sp
->downer
) +
1184 acl_count(sp
->dgroup
) +
1185 acl_count(sp
->dother
) +
1186 acl_count(sp
->dusers
) +
1187 acl_count(sp
->dgroups
);
1188 if (sp
->dclass
.acl_ismask
)
1191 if (vsap
->vsa_mask
& (VSA_DFACLCNT
| VSA_DFACL
))
1192 vsap
->vsa_dfaclcnt
= numacls
;
1197 if (vsap
->vsa_mask
& VSA_DFACL
) {
1198 vsap
->vsa_dfaclentp
=
1199 kmem_zalloc(numacls
* sizeof (aclent_t
), KM_SLEEP
);
1200 aclentp
= vsap
->vsa_dfaclentp
;
1201 formvsec(DEF_USER_OBJ
, sp
->downer
, &aclentp
);
1202 formvsec(DEF_USER
, sp
->dusers
, &aclentp
);
1203 formvsec(DEF_GROUP_OBJ
, sp
->dgroup
, &aclentp
);
1204 formvsec(DEF_GROUP
, sp
->dgroups
, &aclentp
);
1205 formvsec(DEF_OTHER_OBJ
, sp
->dother
, &aclentp
);
1207 if (sp
->dclass
.acl_ismask
) {
1208 aclentp
->a_type
= DEF_CLASS_OBJ
; /* Mask */
1209 aclentp
->a_perm
= sp
->dclass
.acl_maskbits
;
1214 /* Sort the default acl list */
1215 ksort((caddr_t
)vsap
->vsa_dfaclentp
, vsap
->vsa_dfaclcnt
,
1216 sizeof (aclent_t
), cmp2acls
);
1217 if ((err
= acl_validate(vsap
->vsa_dfaclentp
,
1218 vsap
->vsa_dfaclcnt
, DEF_ACL_CHECK
)) != 0) {
1219 if (vsap
->vsa_aclentp
!= NULL
)
1220 kmem_free(vsap
->vsa_aclentp
,
1221 vsap
->vsa_aclcnt
* sizeof (aclent_t
));
1222 kmem_free(vsap
->vsa_dfaclentp
,
1223 vsap
->vsa_dfaclcnt
* sizeof (aclent_t
));
1224 vsap
->vsa_aclentp
= vsap
->vsa_dfaclentp
= NULL
;
1234 acl_free(ufs_ic_acl_t
*aclp
)
1236 while (aclp
!= NULL
) {
1237 ufs_ic_acl_t
*nextaclp
= aclp
->acl_ic_next
;
1238 kmem_free(aclp
, sizeof (ufs_ic_acl_t
));
1244 * ufs_si_free_mem will discard the sp, and the acl hanging off of the
1245 * sp. It is required that the sp not be locked, and not be in the
1248 * input: pointer to sp to discard.
1254 ufs_si_free_mem(si_t
*sp
)
1256 ASSERT(!(sp
->s_flags
& SI_CACHED
));
1257 ASSERT(!RW_LOCK_HELD(&sp
->s_lock
));
1259 * remove from the cache
1260 * free the acl entries
1262 acl_free(sp
->aowner
);
1263 acl_free(sp
->agroup
);
1264 acl_free(sp
->aother
);
1265 acl_free(sp
->ausers
);
1266 acl_free(sp
->agroups
);
1268 acl_free(sp
->downer
);
1269 acl_free(sp
->dgroup
);
1270 acl_free(sp
->dother
);
1271 acl_free(sp
->dusers
);
1272 acl_free(sp
->dgroups
);
1274 rw_destroy(&sp
->s_lock
);
1275 kmem_free(sp
, sizeof (si_t
));
1279 acl_cpy(ufs_ic_acl_t
*saclp
, ufs_ic_acl_t
*daclp
)
1281 ufs_ic_acl_t
*aclp
, *prev_aclp
= NULL
, *aclp1
;
1283 if (saclp
== NULL
) {
1289 for (aclp
= saclp
; aclp
!= NULL
; aclp
= aclp
->acl_ic_next
) {
1290 aclp1
= kmem_alloc(sizeof (ufs_ic_acl_t
), KM_SLEEP
);
1291 aclp1
->acl_ic_next
= NULL
;
1292 aclp1
->acl_ic_who
= aclp
->acl_ic_who
;
1293 aclp1
->acl_ic_perm
= aclp
->acl_ic_perm
;
1294 prev_aclp
->acl_ic_next
= aclp1
;
1295 prev_aclp
= (ufs_ic_acl_t
*)&aclp1
->acl_ic_next
;
1300 * ufs_si_inherit takes a parent acl structure (saclp) and the inode
1301 * of the object that is inheriting an acl and returns the inode
1302 * with the acl linked to it. It also writes the acl to disk if
1303 * it is a unique inode.
1305 * ip - pointer to inode of object inheriting the acl (contents lock)
1306 * tdp - parent inode (rw_lock and contents lock)
1307 * mode - creation modes
1308 * cr - credentials pointer
1311 ufs_si_inherit(struct inode
*ip
, struct inode
*tdp
, o_mode_t mode
, cred_t
*cr
)
1313 si_t
*tsp
, *sp
= tdp
->i_ufs_acl
;
1315 o_mode_t old_modes
, old_uid
, old_gid
;
1318 ASSERT(RW_WRITE_HELD(&ip
->i_contents
));
1319 ASSERT(RW_WRITE_HELD(&tdp
->i_rwlock
));
1320 ASSERT(RW_WRITE_HELD(&tdp
->i_contents
));
1323 * if links/symbolic links, or other invalid acl objects are copied
1324 * or moved to a directory with a default acl do not allow inheritance
1327 if (!CHECK_ACL_ALLOWED(ip
->i_mode
& IFMT
))
1330 /* lock the parent security information */
1331 rw_enter(&sp
->s_lock
, RW_READER
);
1333 ASSERT(((tdp
->i_mode
& IFMT
) == IFDIR
) ||
1334 ((tdp
->i_mode
& IFMT
) == IFATTRDIR
));
1336 mask
= ((sp
->downer
!= NULL
) ? 1 : 0) |
1337 ((sp
->dgroup
!= NULL
) ? 2 : 0) |
1338 ((sp
->dother
!= NULL
) ? 4 : 0);
1341 rw_exit(&sp
->s_lock
);
1346 rw_exit(&sp
->s_lock
);
1350 tsp
= kmem_zalloc(sizeof (si_t
), KM_SLEEP
);
1351 rw_init(&tsp
->s_lock
, NULL
, RW_DEFAULT
, NULL
);
1353 /* copy the default acls */
1355 ASSERT(RW_READ_HELD(&sp
->s_lock
));
1356 acl_cpy(sp
->downer
, (ufs_ic_acl_t
*)&tsp
->aowner
);
1357 acl_cpy(sp
->dgroup
, (ufs_ic_acl_t
*)&tsp
->agroup
);
1358 acl_cpy(sp
->dother
, (ufs_ic_acl_t
*)&tsp
->aother
);
1359 acl_cpy(sp
->dusers
, (ufs_ic_acl_t
*)&tsp
->ausers
);
1360 acl_cpy(sp
->dgroups
, (ufs_ic_acl_t
*)&tsp
->agroups
);
1361 tsp
->aclass
.acl_ismask
= sp
->dclass
.acl_ismask
;
1362 tsp
->aclass
.acl_maskbits
= sp
->dclass
.acl_maskbits
;
1365 * set the owner, group, and other values from the master
1369 MODE2ACL(tsp
->aowner
, (mode
>> 6), ip
->i_uid
);
1370 MODE2ACL(tsp
->agroup
, (mode
>> 3), ip
->i_gid
);
1371 MODE2ACL(tsp
->aother
, (mode
), 0);
1373 if (tsp
->aclass
.acl_ismask
) {
1374 tsp
->aclass
.acl_maskbits
&= mode
>> 3;
1378 /* copy default acl if necessary */
1380 if (((ip
->i_mode
& IFMT
) == IFDIR
) ||
1381 ((ip
->i_mode
& IFMT
) == IFATTRDIR
)) {
1382 acl_cpy(sp
->downer
, (ufs_ic_acl_t
*)&tsp
->downer
);
1383 acl_cpy(sp
->dgroup
, (ufs_ic_acl_t
*)&tsp
->dgroup
);
1384 acl_cpy(sp
->dother
, (ufs_ic_acl_t
*)&tsp
->dother
);
1385 acl_cpy(sp
->dusers
, (ufs_ic_acl_t
*)&tsp
->dusers
);
1386 acl_cpy(sp
->dgroups
, (ufs_ic_acl_t
*)&tsp
->dgroups
);
1387 tsp
->dclass
.acl_ismask
= sp
->dclass
.acl_ismask
;
1388 tsp
->dclass
.acl_maskbits
= sp
->dclass
.acl_maskbits
;
1391 * save the new 9 mode bits in the inode (ip->ic_smode) for
1392 * ufs_getattr. Be sure the mode can be recovered if the store
1395 old_modes
= ip
->i_mode
;
1396 old_uid
= ip
->i_uid
;
1397 old_gid
= ip
->i_gid
;
1399 * store the acl, and get back a new security anchor if
1400 * it is a duplicate.
1402 rw_exit(&sp
->s_lock
);
1403 rw_enter(&ip
->i_rwlock
, RW_WRITER
);
1406 * Suppress out of inodes messages if instructed in the
1409 ip
->i_flag
|= tdp
->i_flag
& IQUIET
;
1411 if ((error
= ufs_si_store(ip
, tsp
, 0, cr
)) != 0) {
1412 ip
->i_mode
= old_modes
;
1413 ip
->i_uid
= old_uid
;
1414 ip
->i_gid
= old_gid
;
1416 ip
->i_flag
&= ~IQUIET
;
1417 rw_exit(&ip
->i_rwlock
);
1422 ufs_acl_cp(si_t
*sp
)
1427 ASSERT(RW_READ_HELD(&sp
->s_lock
));
1428 ASSERT(sp
->s_ref
&& sp
->s_use
);
1430 dsp
= kmem_zalloc(sizeof (si_t
), KM_SLEEP
);
1431 rw_init(&dsp
->s_lock
, NULL
, RW_DEFAULT
, NULL
);
1433 acl_cpy(sp
->aowner
, (ufs_ic_acl_t
*)&dsp
->aowner
);
1434 acl_cpy(sp
->agroup
, (ufs_ic_acl_t
*)&dsp
->agroup
);
1435 acl_cpy(sp
->aother
, (ufs_ic_acl_t
*)&dsp
->aother
);
1436 acl_cpy(sp
->ausers
, (ufs_ic_acl_t
*)&dsp
->ausers
);
1437 acl_cpy(sp
->agroups
, (ufs_ic_acl_t
*)&dsp
->agroups
);
1439 dsp
->aclass
.acl_ismask
= sp
->aclass
.acl_ismask
;
1440 dsp
->aclass
.acl_maskbits
= sp
->aclass
.acl_maskbits
;
1442 acl_cpy(sp
->downer
, (ufs_ic_acl_t
*)&dsp
->downer
);
1443 acl_cpy(sp
->dgroup
, (ufs_ic_acl_t
*)&dsp
->dgroup
);
1444 acl_cpy(sp
->dother
, (ufs_ic_acl_t
*)&dsp
->dother
);
1445 acl_cpy(sp
->dusers
, (ufs_ic_acl_t
*)&dsp
->dusers
);
1446 acl_cpy(sp
->dgroups
, (ufs_ic_acl_t
*)&dsp
->dgroups
);
1448 dsp
->dclass
.acl_ismask
= sp
->dclass
.acl_ismask
;
1449 dsp
->dclass
.acl_maskbits
= sp
->dclass
.acl_maskbits
;
1456 ufs_acl_setattr(struct inode
*ip
, struct vattr
*vap
, cred_t
*cr
)
1460 int mask
= vap
->va_mask
;
1463 ASSERT(RW_WRITE_HELD(&ip
->i_contents
));
1465 if (!(mask
& (AT_MODE
|AT_UID
|AT_GID
)))
1469 * if no regular acl's, nothing to do, so let's get out
1471 if (!(ip
->i_ufs_acl
) || !(ip
->i_ufs_acl
->aowner
))
1474 rw_enter(&ip
->i_ufs_acl
->s_lock
, RW_READER
);
1475 sp
= ufs_acl_cp(ip
->i_ufs_acl
);
1476 ASSERT(sp
!= ip
->i_ufs_acl
);
1479 * set the mask to the group permissions if a mask entry
1480 * exists. Otherwise, set the group obj bits to the group
1481 * permissions. Since non-trivial ACLs always have a mask,
1482 * and the mask is the final arbiter of group permissions,
1483 * setting the mask has the effect of changing the effective
1484 * group permissions, even if the group_obj permissions in
1485 * the ACL aren't changed. Posix P1003.1e states that when
1486 * an ACL mask exists, chmod(2) must set the acl mask (NOT the
1487 * group_obj permissions) to the requested group permissions.
1489 if (mask
& AT_MODE
) {
1490 sp
->aowner
->acl_ic_perm
= (o_mode_t
)(ip
->i_mode
& 0700) >> 6;
1491 if (sp
->aclass
.acl_ismask
)
1492 sp
->aclass
.acl_maskbits
=
1493 (o_mode_t
)(ip
->i_mode
& 070) >> 3;
1495 sp
->agroup
->acl_ic_perm
=
1496 (o_mode_t
)(ip
->i_mode
& 070) >> 3;
1497 sp
->aother
->acl_ic_perm
= (o_mode_t
)(ip
->i_mode
& 07);
1500 if (mask
& AT_UID
) {
1501 /* Caller has verified our privileges */
1502 sp
->aowner
->acl_ic_who
= ip
->i_uid
;
1505 if (mask
& AT_GID
) {
1506 sp
->agroup
->acl_ic_who
= ip
->i_gid
;
1509 rw_exit(&ip
->i_ufs_acl
->s_lock
);
1510 error
= ufs_si_store(ip
, sp
, 0, cr
);
1515 acl_count(ufs_ic_acl_t
*p
)
1520 for (count
= 0, acl
= p
; acl
; acl
= acl
->acl_ic_next
, count
++)
1526 * Takes as input a security structure and generates a buffer
1527 * with fsd's in a form which be written to the shadow inode.
1530 ufs_sectobuf(si_t
*sp
, caddr_t
*buf
, size_t *len
)
1533 size_t def_acl_size
;
1535 struct ufs_fsd
*fsdp
;
1539 * Calc size of buffer to hold all the acls
1541 acl_size
= acl_count(sp
->aowner
) + /* owner */
1542 acl_count(sp
->agroup
) + /* owner group */
1543 acl_count(sp
->aother
) + /* owner other */
1544 acl_count(sp
->ausers
) + /* acl list */
1545 acl_count(sp
->agroups
); /* group alcs */
1546 if (sp
->aclass
.acl_ismask
)
1549 /* Convert to bytes */
1550 acl_size
*= sizeof (ufs_acl_t
);
1552 /* Add fsd header */
1554 acl_size
+= 2 * sizeof (int);
1557 * Calc size of buffer to hold all the default acls
1560 acl_count(sp
->downer
) + /* def owner */
1561 acl_count(sp
->dgroup
) + /* def owner group */
1562 acl_count(sp
->dother
) + /* def owner other */
1563 acl_count(sp
->dusers
) + /* def users */
1564 acl_count(sp
->dgroups
); /* def group acls */
1565 if (sp
->dclass
.acl_ismask
)
1571 def_acl_size
*= sizeof (ufs_acl_t
);
1577 def_acl_size
+= 2 * sizeof (int);
1579 if (acl_size
+ def_acl_size
== 0)
1582 buffer
= kmem_zalloc((acl_size
+ def_acl_size
), KM_SLEEP
);
1583 bufaclp
= (ufs_acl_t
*)buffer
;
1588 /* create fsd and copy acls */
1589 fsdp
= (struct ufs_fsd
*)bufaclp
;
1590 fsdp
->fsd_type
= FSD_ACL
;
1591 bufaclp
= (ufs_acl_t
*)&fsdp
->fsd_data
[0];
1593 ACL_MOVE(sp
->aowner
, USER_OBJ
, bufaclp
);
1594 ACL_MOVE(sp
->agroup
, GROUP_OBJ
, bufaclp
);
1595 ACL_MOVE(sp
->aother
, OTHER_OBJ
, bufaclp
);
1596 ACL_MOVE(sp
->ausers
, USER
, bufaclp
);
1597 ACL_MOVE(sp
->agroups
, GROUP
, bufaclp
);
1599 if (sp
->aclass
.acl_ismask
) {
1600 bufaclp
->acl_tag
= CLASS_OBJ
;
1601 bufaclp
->acl_who
= (uid_t
)sp
->aclass
.acl_ismask
;
1602 bufaclp
->acl_perm
= (o_mode_t
)sp
->aclass
.acl_maskbits
;
1605 ASSERT(acl_size
<= INT_MAX
);
1606 fsdp
->fsd_size
= (int)acl_size
;
1609 if (def_acl_size
== 0)
1612 /* if defaults exist then create fsd and copy default acls */
1613 fsdp
= (struct ufs_fsd
*)bufaclp
;
1614 fsdp
->fsd_type
= FSD_DFACL
;
1615 bufaclp
= (ufs_acl_t
*)&fsdp
->fsd_data
[0];
1617 ACL_MOVE(sp
->downer
, DEF_USER_OBJ
, bufaclp
);
1618 ACL_MOVE(sp
->dgroup
, DEF_GROUP_OBJ
, bufaclp
);
1619 ACL_MOVE(sp
->dother
, DEF_OTHER_OBJ
, bufaclp
);
1620 ACL_MOVE(sp
->dusers
, DEF_USER
, bufaclp
);
1621 ACL_MOVE(sp
->dgroups
, DEF_GROUP
, bufaclp
);
1622 if (sp
->dclass
.acl_ismask
) {
1623 bufaclp
->acl_tag
= DEF_CLASS_OBJ
;
1624 bufaclp
->acl_who
= (uid_t
)sp
->dclass
.acl_ismask
;
1625 bufaclp
->acl_perm
= (o_mode_t
)sp
->dclass
.acl_maskbits
;
1628 ASSERT(def_acl_size
<= INT_MAX
);
1629 fsdp
->fsd_size
= (int)def_acl_size
;
1633 *len
= acl_size
+ def_acl_size
;
1639 * free a shadow inode on disk and in memory
1642 ufs_si_free(si_t
*sp
, struct vfs
*vfsp
, cred_t
*cr
)
1653 rw_enter(&sp
->s_lock
, RW_READER
);
1654 ASSERT(sp
->s_shadow
<= INT_MAX
);
1655 shadow
= (int)sp
->s_shadow
;
1657 rw_exit(&sp
->s_lock
);
1660 * Decrement link count on the shadow inode,
1661 * and decrement reference count on the sip.
1663 if ((err
= ufs_iget_alloced(vfsp
, shadow
, &sip
, cr
)) == 0) {
1664 rw_enter(&sip
->i_contents
, RW_WRITER
);
1665 rw_enter(&sp
->s_lock
, RW_WRITER
);
1666 ASSERT(sp
->s_shadow
== shadow
);
1667 ASSERT(sip
->i_dquot
== 0);
1668 /* Decrement link count */
1669 ASSERT(sip
->i_nlink
> 0);
1671 * bug #1264710 assertion failure below
1673 sp
->s_use
= --sip
->i_nlink
;
1674 ufs_setreclaim(sip
);
1675 TRANS_INODE(sip
->i_ufsvfs
, sip
);
1676 sip
->i_flag
|= ICHG
| IMOD
;
1679 /* Dec ref counts on si referenced by this ip */
1680 refcnt
= --sp
->s_ref
;
1681 signature
= sp
->s_signature
;
1682 ASSERT(sp
->s_ref
>= 0 && sp
->s_ref
<= sp
->s_use
);
1684 * Release s_lock before calling VN_RELE
1685 * (which may want to acquire i_contents).
1687 rw_exit(&sp
->s_lock
);
1688 rw_exit(&sip
->i_contents
);
1691 rw_enter(&sp
->s_lock
, RW_WRITER
);
1692 /* Dec ref counts on si referenced by this ip */
1693 refcnt
= --sp
->s_ref
;
1694 signature
= sp
->s_signature
;
1695 ASSERT(sp
->s_ref
>= 0 && sp
->s_ref
<= sp
->s_use
);
1696 rw_exit(&sp
->s_lock
);
1700 si_cache_del(sp
, signature
);
1705 * Seach the si cache for an si structure by inode #.
1706 * Returns a locked si structure.
1709 * ip - Ptr to an inode on this fs
1710 * spp - Ptr to ptr to si struct for the results, if found.
1712 * Returns: 0 - Success (results in spp)
1713 * 1 - Failure (spp undefined)
1716 si_cachei_get(struct inode
*ip
, si_t
**spp
)
1720 rw_enter(&si_cache_lock
, RW_READER
);
1722 for (sp
= si_cachei
[SI_HASH(ip
->i_shadow
)]; sp
; sp
= sp
->s_forw
)
1723 if (sp
->s_shadow
== ip
->i_shadow
&& sp
->s_dev
== ip
->i_dev
)
1728 rw_exit(&si_cache_lock
);
1732 rw_enter(&sp
->s_lock
, RW_WRITER
);
1734 rw_exit(&si_cache_lock
);
1740 * Seach the si cache by si structure (ie duplicate of the one passed in).
1741 * In order for a match the signatures must be the same and
1742 * the devices must be the same, the acls must match and
1743 * link count of the cached shadow must be less than the
1744 * size of ic_nlink - 1. MAXLINK - 1 is used to allow the count
1745 * to be incremented one more time by the caller.
1746 * Returns a locked si structure.
1749 * ip - Ptr to an inode on this fs
1750 * spi - Ptr to si the struct we're searching the cache for.
1751 * spp - Ptr to ptr to si struct for the results, if found.
1753 * Returns: 0 - Success (results in spp)
1754 * 1 - Failure (spp undefined)
1757 si_cachea_get(struct inode
*ip
, si_t
*spi
, si_t
**spp
)
1761 spi
->s_dev
= ip
->i_dev
;
1762 spi
->s_signature
= si_signature(spi
);
1763 rw_enter(&si_cache_lock
, RW_READER
);
1765 for (sp
= si_cachea
[SI_HASH(spi
->s_signature
)]; sp
; sp
= sp
->s_next
) {
1766 if (sp
->s_signature
== spi
->s_signature
&&
1767 sp
->s_dev
== spi
->s_dev
&&
1768 sp
->s_use
> 0 && /* deleting */
1769 sp
->s_use
<= (MAXLINK
- 1) && /* Too many links */
1776 rw_exit(&si_cache_lock
);
1780 rw_enter(&sp
->s_lock
, RW_WRITER
);
1782 spi
->s_shadow
= sp
->s_shadow
; /* XXX For debugging */
1783 rw_exit(&si_cache_lock
);
1789 * Place an si structure in the si cache. May cause duplicates.
1792 * sp - Ptr to the si struct to add to the cache.
1794 * Returns: Nothing (void)
1797 si_cache_put(si_t
*sp
)
1801 ASSERT(sp
->s_fore
== NULL
);
1802 rw_enter(&si_cache_lock
, RW_WRITER
);
1803 if (!sp
->s_signature
)
1804 sp
->s_signature
= si_signature(sp
);
1805 sp
->s_flags
|= SI_CACHED
;
1808 /* The 'by acl' chains */
1809 tspp
= &si_cachea
[SI_HASH(sp
->s_signature
)];
1813 /* The 'by inode' chains */
1814 tspp
= &si_cachei
[SI_HASH(sp
->s_shadow
)];
1818 rw_exit(&si_cache_lock
);
1822 * The sp passed in is a candidate for deletion from the cache. We acquire
1823 * the cache lock first, so no cache searches can be done. Then we search
1824 * for the acl in the cache, and if we find it we can lock it and check that
1825 * nobody else attached to it while we were acquiring the locks. If the acl
1826 * is in the cache and still has a zero reference count, then we remove it
1827 * from the cache and deallocate it. If the reference count is non-zero or
1828 * it is not found in the cache, then someone else attached to it or has
1829 * already freed it, so we just return.
1832 * sp - Ptr to the sp struct which is the candicate for deletion.
1833 * signature - the signature for the acl for lookup in the hash table
1835 * Returns: Nothing (void)
1838 si_cache_del(si_t
*sp
, int signature
)
1845 * Unlink & free the sp from the other queues, then destroy it.
1846 * Search the 'by acl' chain first, then the 'by inode' chain
1847 * after the acl is locked.
1849 rw_enter(&si_cache_lock
, RW_WRITER
);
1850 hash
= SI_HASH(signature
);
1851 for (tspp
= &si_cachea
[hash
]; *tspp
; tspp
= &(*tspp
)->s_next
) {
1854 * Wait to grab the acl lock until after the acl has
1855 * been found in the cache. Otherwise it might try to
1856 * grab a lock that has already been destroyed, or
1857 * delete an acl that has already been freed.
1859 rw_enter(&sp
->s_lock
, RW_WRITER
);
1860 /* See if someone else attached to it */
1862 rw_exit(&sp
->s_lock
);
1863 rw_exit(&si_cache_lock
);
1866 ASSERT(sp
->s_fore
== NULL
);
1867 ASSERT(sp
->s_flags
& SI_CACHED
);
1875 * If the acl was not in the cache, we assume another thread has
1876 * deleted it already. This could happen if another thread attaches to
1877 * the acl and then releases it after this thread has already found the
1878 * reference count to be zero but has not yet taken the cache lock.
1879 * Both threads end up seeing a reference count of zero, and call into
1880 * si_cache_del. See bug 4244827 for details on the race condition.
1882 if (foundacl
== 0) {
1883 rw_exit(&si_cache_lock
);
1887 /* Now check the 'by inode' chain */
1888 hash
= SI_HASH(sp
->s_shadow
);
1889 for (tspp
= &si_cachei
[hash
]; *tspp
; tspp
= &(*tspp
)->s_forw
) {
1897 * At this point, we can unlock everything because this si
1898 * is no longer in the cache, thus cannot be attached to.
1900 rw_exit(&sp
->s_lock
);
1901 rw_exit(&si_cache_lock
);
1902 sp
->s_flags
&= ~SI_CACHED
;
1903 (void) ufs_si_free_mem(sp
);
1907 * Alloc the hash buckets for the si cache & initialize
1908 * the unreferenced anchor and the cache lock.
1913 rw_init(&si_cache_lock
, NULL
, RW_DEFAULT
, NULL
);
1915 /* The 'by acl' headers */
1916 si_cachea
= kmem_zalloc(si_cachecnt
* sizeof (si_t
*), KM_SLEEP
);
1917 /* The 'by inode' headers */
1918 si_cachei
= kmem_zalloc(si_cachecnt
* sizeof (si_t
*), KM_SLEEP
);
1922 * aclcksum takes an acl and generates a checksum. It takes as input
1923 * the acl to start at.
1925 * s_aclp - pointer to starting acl
1930 aclcksum(ufs_ic_acl_t
*s_aclp
)
1934 for (aclp
= s_aclp
; aclp
; aclp
= aclp
->acl_ic_next
) {
1935 signature
+= aclp
->acl_ic_perm
;
1936 signature
+= aclp
->acl_ic_who
;
1942 * Generate a unique signature for an si structure. Used by the
1943 * search routine si_cachea_get() to quickly identify candidates
1944 * prior to calling si_cmp().
1946 * sp - Ptr to the si struct to generate the signature for.
1948 * Returns: A signature for the si struct (really a checksum)
1951 si_signature(si_t
*sp
)
1953 int signature
= sp
->s_dev
;
1955 signature
+= aclcksum(sp
->aowner
) + aclcksum(sp
->agroup
) +
1956 aclcksum(sp
->aother
) + aclcksum(sp
->ausers
) +
1957 aclcksum(sp
->agroups
) + aclcksum(sp
->downer
) +
1958 aclcksum(sp
->dgroup
) + aclcksum(sp
->dother
) +
1959 aclcksum(sp
->dusers
) + aclcksum(sp
->dgroups
);
1960 if (sp
->aclass
.acl_ismask
)
1961 signature
+= sp
->aclass
.acl_maskbits
;
1962 if (sp
->dclass
.acl_ismask
)
1963 signature
+= sp
->dclass
.acl_maskbits
;
1969 * aclcmp compares to acls to see if they are identical.
1974 * returns 0 if equal and 1 if not equal
1977 aclcmp(ufs_ic_acl_t
*aclin1p
, ufs_ic_acl_t
*aclin2p
)
1979 ufs_ic_acl_t
*aclp1
;
1980 ufs_ic_acl_t
*aclp2
;
1983 * if the starting pointers are equal then they are equal so
1986 if (aclin1p
== aclin2p
)
1989 * check element by element
1991 for (aclp1
= aclin1p
, aclp2
= aclin2p
; aclp1
&& aclp2
;
1992 aclp1
= aclp1
->acl_ic_next
, aclp2
= aclp2
->acl_ic_next
) {
1993 if (aclp1
->acl_ic_perm
!= aclp2
->acl_ic_perm
||
1994 aclp1
->acl_ic_who
!= aclp2
->acl_ic_who
)
1998 * both must be zero (at the end of the acl)
2007 * Do extensive, field-by-field compare of two si structures. Returns
2008 * 0 if they are exactly identical, 1 otherwise.
2011 * sp1 - Ptr to 1st si struct
2012 * sp2 - Ptr to 2nd si struct
2019 si_cmp(si_t
*sp1
, si_t
*sp2
)
2021 if (sp1
->s_dev
!= sp2
->s_dev
)
2023 if (aclcmp(sp1
->aowner
, sp2
->aowner
) ||
2024 aclcmp(sp1
->agroup
, sp2
->agroup
) ||
2025 aclcmp(sp1
->aother
, sp2
->aother
) ||
2026 aclcmp(sp1
->ausers
, sp2
->ausers
) ||
2027 aclcmp(sp1
->agroups
, sp2
->agroups
) ||
2028 aclcmp(sp1
->downer
, sp2
->downer
) ||
2029 aclcmp(sp1
->dgroup
, sp2
->dgroup
) ||
2030 aclcmp(sp1
->dother
, sp2
->dother
) ||
2031 aclcmp(sp1
->dusers
, sp2
->dusers
) ||
2032 aclcmp(sp1
->dgroups
, sp2
->dgroups
))
2034 if (sp1
->aclass
.acl_ismask
!= sp2
->aclass
.acl_ismask
)
2036 if (sp1
->dclass
.acl_ismask
!= sp2
->dclass
.acl_ismask
)
2038 if (sp1
->aclass
.acl_ismask
&&
2039 sp1
->aclass
.acl_maskbits
!= sp2
->aclass
.acl_maskbits
)
2041 if (sp1
->dclass
.acl_ismask
&&
2042 sp1
->dclass
.acl_maskbits
!= sp2
->dclass
.acl_maskbits
)
2049 * Remove all acls associated with a device. All acls must have
2050 * a reference count of zero.
2053 * device - device to remove from the cache
2059 ufs_si_cache_flush(dev_t dev
)
2064 rw_enter(&si_cache_lock
, RW_WRITER
);
2065 for (i
= 0; i
< si_cachecnt
; i
++) {
2066 tspp
= &si_cachea
[i
];
2068 if ((*tspp
)->s_dev
== dev
) {
2069 *tspp
= (*tspp
)->s_next
;
2071 tspp
= &(*tspp
)->s_next
;
2075 for (i
= 0; i
< si_cachecnt
; i
++) {
2076 tspp
= &si_cachei
[i
];
2078 if ((*tspp
)->s_dev
== dev
) {
2080 *tspp
= (*tspp
)->s_forw
;
2081 tsp
->s_flags
&= ~SI_CACHED
;
2082 ufs_si_free_mem(tsp
);
2084 tspp
= &(*tspp
)->s_forw
;
2088 rw_exit(&si_cache_lock
);
2092 * ufs_si_del is used to unhook a sp from a inode in memory
2094 * ip is the inode to remove the sp from.
2097 ufs_si_del(struct inode
*ip
)
2099 si_t
*sp
= ip
->i_ufs_acl
;
2104 rw_enter(&sp
->s_lock
, RW_WRITER
);
2105 refcnt
= --sp
->s_ref
;
2106 signature
= sp
->s_signature
;
2107 ASSERT(sp
->s_ref
>= 0 && sp
->s_ref
<= sp
->s_use
);
2108 rw_exit(&sp
->s_lock
);
2110 si_cache_del(sp
, signature
);
2111 ip
->i_ufs_acl
= NULL
;