4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright (c) 1993-1997 by Sun Microsystems, Inc.
28 #pragma ident "%Z%%M% %I% %E% SMI"
33 * Sort an ACL by entry type according to the following order:
34 * USER_OBJ, USER, GROUP_OBJ, GROUP, CLASS_OBJ, OTHER_OBJ
35 * DEF_USER_OBJ, DEF_USER, DEF_GROUP_OBJ, DEF_GROUP, DEF_CLASS_OBJ,
37 * For USER, GROUP, DEF_USER, and DEF_GROUP entries, the entries
38 * are further sorted by ids.
44 #define TOTAL_ENTRY_TYPES 12
47 * This maps the entry defined value to a value for sorting.
48 * These values may not be the same. It is easier to add an
49 * entry type with this map.
51 * Because the defines and sorting order are not the same,
52 * the following map_to_sort table is needed.
59 static struct map map_to_sort
[] = {
75 static int entrycmp(const aclent_t
*, const aclent_t
*);
76 static int idcmp(const aclent_t
*, const aclent_t
*);
77 static void sortid(aclent_t
*, int, int);
80 aclsort(int nentries
, int calcmask
, aclent_t
*aclbufp
)
83 unsigned int newmask
= 0;
88 /* check validity first before sorting */
89 if (aclcheck(aclbufp
, nentries
, &which
) != 0)
93 * Performance enhancement:
94 * We change entry type to sort order in the ACL, do the sorting.
95 * We then change sort order back to entry type.
96 * This makes entrycmp() very "light" and thus improves performance.
97 * Contrast to original implementation that had to find out
98 * the sorting order each time it is called.
100 for (tp
= aclbufp
, i
= 0; i
< nentries
; tp
++, i
++) {
101 for (k
= 1; k
<= TOTAL_ENTRY_TYPES
; k
++) {
102 if (tp
->a_type
== map_to_sort
[k
].entry_type
) {
103 tp
->a_type
= map_to_sort
[k
].sort_order
;
109 /* typecast to remove incompatible type warning */
110 qsort(aclbufp
, nentries
, sizeof (aclent_t
),
111 (int (*)(const void *, const void *))entrycmp
);
113 for (tp
= aclbufp
, i
= 0; i
< nentries
; tp
++, i
++) {
114 for (k
= 1; k
<= TOTAL_ENTRY_TYPES
; k
++) {
115 if (tp
->a_type
== map_to_sort
[k
].sort_order
) {
116 tp
->a_type
= map_to_sort
[k
].entry_type
;
123 * Start sorting id within USER and GROUP
124 * sortid() could return a pointer and entries left
125 * so that we dont have to search from the beginning
126 * every time it calls
128 sortid(aclbufp
, nentries
, USER
);
129 sortid(aclbufp
, nentries
, GROUP
);
130 sortid(aclbufp
, nentries
, DEF_USER
);
131 sortid(aclbufp
, nentries
, DEF_GROUP
);
134 * Recalculate mask entry
138 * At this point, ACL is valid and sorted. We may find a
139 * CLASS_OBJ entry and stop. Because of the case of minimum ACL,
140 * we still have to check till OTHER_OBJ entry is shown.
142 for (tp
= aclbufp
; tp
->a_type
!= OTHER_OBJ
; tp
++) {
143 if (tp
->a_type
== USER
|| tp
->a_type
== GROUP
||
144 tp
->a_type
== GROUP_OBJ
)
145 newmask
|= tp
->a_perm
;
146 if (tp
->a_type
== CLASS_OBJ
)
149 if (tp
->a_type
== CLASS_OBJ
)
150 tp
->a_perm
= (unsigned char)newmask
;
156 * sortid() sorts the ids with the same entry type in increasing order
159 sortid(aclent_t
*ap
, int cnt
, int type
)
162 aclent_t
*startp
; /* start of the desired entry type */
165 for (tp
= ap
; cnt
-- > 0; tp
++) {
166 if (tp
->a_type
!= type
)
170 for (tp
++, cnt
--; cnt
> 0 && tp
->a_type
== type
; tp
++, cnt
--)
172 /* typecast to remove incompatible type warning */
173 qsort(startp
, howmany
, sizeof (aclent_t
),
174 (int (*)(const void*, const void*))idcmp
);
179 * compare the field a_type
182 entrycmp(const aclent_t
*i
, const aclent_t
*j
)
184 return ((int)(i
->a_type
) - (int)(j
->a_type
));
188 * compare the field a_id
191 idcmp(const aclent_t
*i
, const aclent_t
*j
)
193 return ((int)(i
->a_id
) - (int)(j
->a_id
));