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]
23 * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved
29 * routines to manipulate access control lists, mapping between
30 * the data structures required by the filesystem ACL system calls
31 * and the representation used in our fileinfo structure.
44 * Solaris 2.4 libc.so does not contain this entry point, so if we
45 * want to build a 2.4 version of filesync, we need to provide a
46 * dummy entry point that will fail when-ever it is called.
50 static int acl(const char *name
, int opcode
, int count
, aclent_t
*acls
)
61 * to read the ACL (if any) from a file into a fileinfo structure
65 * pointer to fileinfo structure
68 * number of ACL entries
71 get_acls(const char *name
, struct fileinfo
*ip
)
74 static aclent_t acls
[MAX_ACL_ENTRIES
];
77 count
= acl(name
, GETACL
, MAX_ACL_ENTRIES
, acls
);
81 /* with a count of 3 or 4 there may not be any real ones */
85 /* look for anything beyond the normal unix protection */
86 for (i
= 0; i
< count
; i
++)
87 switch (acls
[i
].a_type
) {
88 default: /* weird types are real */
95 continue; /* all file have these */
98 return (0); /* nothing interesting */
101 /* allocate an array to hold the acls */
102 list
= (aclent_t
*) malloc(count
* sizeof (*list
));
104 nomem("Access Control List");
106 /* copy the acls into the new list */
107 for (i
= 0; i
< count
; i
++) {
108 list
[i
].a_type
= acls
[i
].a_type
;
109 list
[i
].a_id
= acls
[i
].a_id
;
110 list
[i
].a_perm
= acls
[i
].a_perm
;
114 ip
->f_numacls
= count
;
115 return (ip
->f_numacls
);
123 * determine whether or not two ACLs are the same
126 * pointer to first fileinfo
127 * pointer to second fileinfo
134 cmp_acls(struct fileinfo
*f1
, struct fileinfo
*f2
)
137 if (f1
->f_numacls
!= f2
->f_numacls
)
140 if (f1
->f_numacls
== 0)
143 for (i
= 0; i
< f1
->f_numacls
; i
++) {
144 if (f1
->f_acls
[i
].a_type
!= f2
->f_acls
[i
].a_type
)
146 if (f1
->f_acls
[i
].a_id
!= f2
->f_acls
[i
].a_id
)
148 if (f1
->f_acls
[i
].a_perm
!= f2
->f_acls
[i
].a_perm
)
160 * to write the ACL of a file
164 * fileinfo pointer (which contains an acl pointer)
170 set_acls(const char *name
, struct fileinfo
*fp
)
173 aclent_t acls
[4], *list
;
175 if (fp
->f_numacls
== 0) {
176 /* fabricate a standard set of bogus ACLs */
177 acls
[0].a_type
= USER_OBJ
;
178 acls
[0].a_id
= fp
->f_uid
;
179 acls
[0].a_perm
= (fp
->f_mode
>> 6) & 7;
181 acls
[1].a_type
= GROUP_OBJ
;
182 acls
[1].a_id
= fp
->f_gid
;
183 acls
[1].a_perm
= (fp
->f_mode
>> 3) & 7;
185 acls
[2].a_type
= CLASS_OBJ
;
187 acls
[2].a_perm
= (fp
->f_mode
>> 6) & 7;
189 acls
[3].a_type
= OTHER_OBJ
;
191 acls
[3].a_perm
= fp
->f_mode
& 7;
196 nacl
= fp
->f_numacls
;
200 rc
= acl(name
, SETACL
, nacl
, list
);
202 /* non-negative number mean success */
214 * to map an acl into arguments for a setfacl command
217 * number of elements in list
221 * pointer to character buffer containing arguments
224 *show_acls(int numacl
, aclent_t
*list
)
228 static char buf
[ MAX_LINE
];
241 for (i
= 0; i
< numacl
; i
++) {
242 type
= list
[i
].a_type
;
244 perm
= list
[i
].a_perm
;
249 /* note whether this is per-file or default */
250 if (type
& ACL_DEFAULT
) {
255 /* print out the entry type */
256 if (type
& (USER_OBJ
|USER
)) {
259 } else if (type
& (GROUP_OBJ
|GROUP
)) {
262 } else if (type
& OTHER_OBJ
) {
265 } else if (type
& CLASS_OBJ
) {
270 /* print out the ID for this ACL */
271 if (type
& (USER_OBJ
|GROUP_OBJ
))
273 else if (type
& (USER
|GROUP
)) {
274 for (j
= 1; id
/j
> 10; j
*= 10);
285 /* print out the permissions for this ACL */
286 *s
++ = (perm
& 04) ? 'r' : '-';
287 *s
++ = (perm
& 02) ? 'w' : '-';
288 *s
++ = (perm
& 01) ? 'x' : '-';